为什么有些库提供无指针访问,而有些库不提供? 《C++编程》可以用多种范式来完成。可以不使用指针、标准指针甚至智能指针。用于在屏幕上显示图形的主流库正在处理不同的情况。例如,在SFML中,不使用指针语法就可以创建新窗口,而在Ogre3D中则需要使用指针 // SFML without pointer sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window"); // SFML with pointers sf::Window* m_Window; // Ogre3d with pointer RenderWindow *renderWindow = root->createRenderWindow("Main",320,240,false);

为什么有些库提供无指针访问,而有些库不提供? 《C++编程》可以用多种范式来完成。可以不使用指针、标准指针甚至智能指针。用于在屏幕上显示图形的主流库正在处理不同的情况。例如,在SFML中,不使用指针语法就可以创建新窗口,而在Ogre3D中则需要使用指针 // SFML without pointer sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window"); // SFML with pointers sf::Window* m_Window; // Ogre3d with pointer RenderWindow *renderWindow = root->createRenderWindow("Main",320,240,false);,c++,pointers,C++,Pointers,使用指针总是可能的,因为指针是更强大的概念。所以我的问题是:SFML中有什么诀窍可以为最终用户提供无指针API?我们如何编写可以在没有指针的情况下实例化的类?或者缺少指针是个坏主意,而SFML是错误的,因为他们不建议使用指针?这取决于特定API打算执行什么: // SFML without pointer sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window"); 在上述情况下,库调用构造函数,因此它不能是指针 // Ogr

使用指针总是可能的,因为指针是更强大的概念。所以我的问题是:SFML中有什么诀窍可以为最终用户提供无指针API?我们如何编写可以在没有指针的情况下实例化的类?或者缺少指针是个坏主意,而SFML是错误的,因为他们不建议使用指针?

这取决于特定API打算执行什么:

// SFML without pointer
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
在上述情况下,库调用构造函数,因此它不能是指针

// Ogre3d with pointer
RenderWindow *renderWindow = root->createRenderWindow("Main",320,240,false);

对于ogre3d来说,它们的实现方式是不同的。这是一个设计模式决策。他们可能在幕后使用了
工厂
设计模式。

这取决于特定API打算执行什么:

// SFML without pointer
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
在上述情况下,库调用构造函数,因此它不能是指针

// Ogre3d with pointer
RenderWindow *renderWindow = root->createRenderWindow("Main",320,240,false);

对于ogre3d来说,它们的实现方式是不同的。这是一个设计模式决策。他们可能在幕后使用了
工厂
设计模式。

图形库的特殊之处是什么

这里的问题是,图书馆如何支持所有权管理。处理原始指针可能导致内存泄漏/死对象。因此,一些libs提供商正在引导用户进行自己的内存管理。gtkmm有自己的智能指针,使用它们很常见

总是可以使用指针

不! 1) 这不总是可能的!如果库提供程序保护构造函数并允许您仅通过创建方法创建实例,则无法获取库对象的原始指针

,…因为指针是更强大的概念

没有什么比智能指针或引用更强大的了。唯一不能直接完成的事情是使用虚拟调度。但这也可以在智能指针实现中进行管理。我看没有理由接受你的说法;)

。。。我们如何编写可以在没有指针的情况下实例化的类

您可以在没有指针的情况下实例化每个类。简单地

Type instanceVar{<Constructor Parms>}; 
类型instanceVar{};
我会做好的。无需使用
new
new@

还是缺少指针是个坏主意

不!如果有一种解决所有权问题的通用方法,这是一个好主意。智能指针是一些其他概念,可以在库内部容器中处理


我个人的想法是,我想决定如何使用图书馆。由于C++仍然提供智能指针,所以我不想使用特定于库的指针。但是很多普通的LIBS早在智能指针是C++的一部分之前就已经开始开发了。因此,他们仍然有自己的实现和所有权管理。这是我不喜欢的东西,但这是我个人的观点,也是基于这个观点的

这里的图形库有什么特别之处

这里的问题是,图书馆如何支持所有权管理。处理原始指针可能导致内存泄漏/死对象。因此,一些libs提供商正在引导用户进行自己的内存管理。gtkmm有自己的智能指针,使用它们很常见

总是可以使用指针

不! 1) 这不总是可能的!如果库提供程序保护构造函数并允许您仅通过创建方法创建实例,则无法获取库对象的原始指针

,…因为指针是更强大的概念

没有什么比智能指针或引用更强大的了。唯一不能直接完成的事情是使用虚拟调度。但这也可以在智能指针实现中进行管理。我看没有理由接受你的说法;)

。。。我们如何编写可以在没有指针的情况下实例化的类

您可以在没有指针的情况下实例化每个类。简单地

Type instanceVar{<Constructor Parms>}; 
类型instanceVar{};
我会做好的。无需使用
new
new@

还是缺少指针是个坏主意

不!如果有一种解决所有权问题的通用方法,这是一个好主意。智能指针是一些其他概念,可以在库内部容器中处理

我个人的想法是,我想决定如何使用图书馆。由于C++仍然提供智能指针,所以我不想使用特定于库的指针。但是很多普通的LIBS早在智能指针是C++的一部分之前就已经开始开发了。因此,他们仍然有自己的实现和所有权管理。这是我不喜欢的东西,但这是我个人的观点,也是基于这个观点的

总体思路是:

变量必须保持在范围内。如果在函数中创建变量,则该变量将在函数结束时停止存在。只有将变量放在堆栈而不是堆上时,这才是正确的。所有变量都在堆栈上,唯一的例外是使用新的、静态的或全局变量创建的变量。因此,如果不使用new和指针,变量的内容将丢失。例如:

char* readName()
{
    char name[64];
    scanf("%s", name);
    return name;
}

int main()
{
    char* name = readName();
    std::cout << name << std::endl;
}
这不是您想要的,您会得到随机数据,因为您的变量停止存在,因为它在堆栈上。让我们使用堆上的一个变量来执行此操作,这样它就不会被删除

#include <iostream>
#include <stdio.h>
using namespace std;

char* readName()
{
    char* name = new char(64);
    scanf("%s", name);
    return name;
}

int main()
{
    char* name = readName();
    std::cout << name << std::endl;
    delete[] name; //you have to delete heap variables to get the RAM back
}
等一下,你会抱怨的。这是真的,因为我想用数组向您展示它。如果图形库使用指向视频内存的指针,vi
struct Level
{
 size_t data[1*1024*1024*1024]; //1 gigabyte data
};

class LevelWrapper
{
  Level level;
  LevelWrapper() : level()
  {

  }
  inline Level& getLevel()
  {
    return level;
  }
};

Level* getLevelPointer()
{
    Level level = new Level();
    return level;
}

Level getLevelCopy()
{
    Level level;
    return level;
}

void main()
{
   Level* level = getLevelPointer(); //level lives on the heap
   Level level2 = getLevelCopy(); //level is created on copied to main 
   LevelWrapper wrapper;
   Level& level3 = wrapper.level(); //level lives in wrapper, using a reference to get it
}
#include <stdio.h>
#include <malloc.h>

struct Person
{
   int age;
   char* name;
};


void main()
{
        struct Person p1;
        p1.name = (char*) malloc(64*sizeof(char));
        p1.name = "Junior";
        p1.age = 16;
        struct Person p2 = p1;

        printf("%p %p \n", p1.name, p2.name);
}

./pers 
0x400624 0x400624 
std::shared_ptr<MyObject> MyObjectPtr(new MyObject("Strawberries"));