在阅读了关于指针和引用之间差异的问题之后,我决定使用引用而不是指针用于我的类字段.然而,似乎这是不可能的,因为它们不能被宣布为未初始化(对吧?).
在我现在正在处理的特定场景中,我不想使用正常变量(顺便说一下它们的正确用语是什么?)因为它们在我声明它们时会自动初始化.
在我的代码片段中,bar1自动使用默认构造函数实例化(这不是我想要的),而bar2导致编译器错误,因为你不能使用未初始化的引用(正确吗?),而*bar3很高兴因为指针可以声明未初始化(顺便说一下,最好将此设置为NULL吗?).
class Foo { public: Bar bar1; Bar &bar2; Bar *bar3; }
看起来我必须在这种情况下使用指针,这是真的吗?另外,使用变量的最佳方法是什么? - >语法有点麻烦......运气好吗?什么智能指针,等等?这有关系吗?
尝试在我的类中实现引用变量字段并在构造函数中初始化它之后,为什么我会收到以下错误?
../src/textures/VTexture.cpp: In constructor ‘vimrid::textures::VTexture::VTexture()’: ../src/textures/VTexture.cpp:19: error: uninitialized reference member ‘vimrid::textures::VTexture::image’
这是真正的代码:
// VTexture.h class VTexture { public: VTexture(vimrid::imaging::ImageMatrix &rImage); private: vimrid::imaging::ImageMatrix ℑ } // VTexture.cpp VTexture::VTexture(ImageMatrix &rImage) : image(rImage) { }
我也试过在标题中这样做,但没有运气(我得到同样的错误).
// VTexture.h class VTexture { public: VTexture(vimrid::imaging::ImageMatrix &rimage) : image(rImage) { } }
弗雷德拉森 - 是的!有一个默认的构造函数; 我忽略了它,因为我认为这与问题无关(我多么愚蠢).删除默认构造函数后,我导致编译器错误,因为该类与std :: vector一起使用,需要有一个默认构造函数.因此看起来我必须使用默认构造函数,因此必须使用指针.羞耻......或者是吗?:)
对问题1的回答:
然而,似乎这是不可能的,因为它们[引用]不能被声明为未初始化(对吧?).
对.
对问题2的回答:
在我的代码片段中,bar1会自动使用默认构造函数实例化(这不是我想要的),而bar2会导致编译器错误,因为您无法使用未初始化的引用(正确吗?),
您在构造函数的初始化列表中初始化类的引用:
class Foo { public: Foo(Bar &rBar) : bar2(rBar), bar3(NULL) { } Bar bar1; Bar &bar2; Bar *bar3; }
对问题3的回答:
在我现在正在处理的特定场景中,我不想使用正常变量(顺便说一下它们的正确用语是什么?)
他们没有正确的名称,通常你可以说大多数讨论的指针(除了这个),你需要讨论的一切也适用于参考.您可以通过initailizer列表以相同的方式初始化非指针,非引用成员.
class Foo { public: Foo() : x(0), y(4) { } int x, y; };
对问题4的回答:
指针可以声明为未初始化(顺便说一下,最好将它设置为NULL吗?).
他们可以被宣布为未初始化的是.最好将它们初始化为NULL,因为这样你就可以检查它们是否有效.
int *p = NULL; //... //Later in code if(p) { //Do something with p }
对问题5的回答:
看起来我必须在这种情况下使用指针,这是真的吗?另外,使用变量的最佳方法是什么?
您可以使用指针或引用,但不能重新分配引用,并且引用不能为NULL.指针就像任何其他变量一样,就像int一样,但它包含一个内存地址.数组是另一个变量的别名.
指针有自己的内存地址,而数组应该被视为共享它引用的变量的地址.
使用引用,在初始化和声明之后,就像使用它引用的变量一样使用它.没有特殊的语法.
使用指针,要访问它所拥有的地址处的值,您必须dereference
使用指针.你可以在它之前放一个*来做到这一点.
int x=0; int *p = &x;//p holds the address of x int &r(x);//r is a reference to x //From this point *p == r == x *p = 3;//change x to 3 r = 4;//change x to 4 //Up until now int y=0; p = &y;//p now holds the address of y instead.
对问题6的回答:
智能指针等怎么样?这有关系吗?
使用智能指针(请参阅boost :: shared_ptr),以便在堆上分配时,无需手动释放内存.我上面给出的所有示例都没有在堆上分配.这是一个使用智能指针有帮助的例子.
void createANewFooAndCallOneOfItsMethods(Bar &bar) { Foo *p = new Foo(bar); p->f(); //The memory for p is never freed here, but if you would have used a smart pointer then it would have been freed here. }
对问题7的回答:
更新1:
尝试在我的类中实现引用变量字段并在构造函数中初始化它之后,为什么我会收到以下错误?
问题是您没有指定初始化列表.请参阅我对上述问题2的回答.结肠后的一切:
class VTexture { public: VTexture(vimrid::imaging::ImageMatrix &rImage) : image(rImage) { } private: vimrid::imaging::ImageMatrix ℑ }
它们可以初始化.您只需使用成员初始化列表.
Foo::Foo(...) : bar1(...), bar2(...), bar3(...) { // Whatever }
以这种方式初始化所有成员变量是个好主意.否则,对于除基本类型之外的其他类,C++将使用默认构造函数初始化它们.在大括号内分配它们实际上是重新分配它们,而不是初始化它们.
另外,请记住,成员初始化列表指定如何初始化成员变量,而不是ORDER.成员按声明的顺序进行初始化,而不是按初始化程序的顺序进行初始化.