当前位置:  开发笔记 > 编程语言 > 正文

我必须为我的C++类字段使用指针吗?

如何解决《我必须为我的C++类字段使用指针吗?》经验,为你挑选了2个好方法。

在阅读了关于指针和引用之间差异的问题之后,我决定使用引用而不是指针用于我的类字段.然而,似乎这是不可能的,因为它们不能被宣布为未初始化(对吧?).

在我现在正在处理的特定场景中,我不想使用正常变量(顺便说一下它们的正确用语是什么?)因为它们在我声明它们时会自动初始化.

在我的代码片段中,bar1自动使用默认构造函数实例化(这不是我想要的),而bar2导致编译器错误,因为你不能使用未初始化的引用(正确吗?),而*bar3很高兴因为指针可以声明未初始化(顺便说一下,最好将此设置为NULL吗?).

class Foo
{
public:
    Bar bar1;
    Bar &bar2;
    Bar *bar3;
}

看起来我必须在这种情况下使用指针,这是真的吗?另外,使用变量的最佳方法是什么? - >语法有点麻烦......运气好吗?什么智能指针,等等?这有关系吗?

更新1:

尝试在我的类中实现引用变量字段并在构造函数中初始化它之后,为什么我会收到以下错误?

../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) { }
}

更新2:

弗雷德拉森 - 是的!有一个默认的构造函数; 我忽略了它,因为我认为这与问题无关(我多么愚蠢).删除默认构造函数后,我导致编译器错误,因为该类与std :: vector一起使用,需要有一个默认构造函数.因此看起来我必须使用默认构造函数,因此必须使用指针.羞耻......或者是吗?:)



1> Brian R. Bon..:

对问题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 ℑ
}



2> Fred Larson..:

它们可以初始化.您只需使用成员初始化列表.

Foo::Foo(...) : bar1(...), bar2(...), bar3(...)
{
  // Whatever
}

以这种方式初始化所有成员变量是个好主意.否则,对于除基本类型之外的其他类,C++将使用默认构造函数初始化它们.在大括号内分配它们实际上是重新分配它们,而不是初始化它们.

另外,请记住,成员初始化列表指定如何初始化成员变量,而不是ORDER.成员按声明的顺序进行初始化,而不是按初始化程序的顺序进行初始化.

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有