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

C++ 我必须为我的C+使用指针吗+;类字段?,c++,pointers,reference,C++,Pointers,Reference,在阅读了上的一个问题后,我决定对我的类字段使用引用而不是指针。然而,这似乎是不可能的,因为它们不能被声明为未初始化(对吗?) 在我现在正在处理的特定场景中,我不想使用普通变量(顺便问一下,它们的正确术语是什么?),因为当我声明它们时,它们会自动初始化 在我的代码片段中,bar1会自动使用默认构造函数实例化(这不是我想要的),&bar2会导致编译器错误,因为您不能使用未初始化的引用(正确吗?),而*bar3也很高兴,因为指针可以声明为未初始化(顺便问一下,将其设置为NULL是否是最佳做法?) 看起

在阅读了上的一个问题后,我决定对我的类字段使用引用而不是指针。然而,这似乎是不可能的,因为它们不能被声明为未初始化(对吗?)

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

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

看起来我必须在这个场景中使用指针,这是真的吗?另外,使用变量的最佳方式是什么?->语法有点麻烦。。。运气不好?等等呢?这是否相关

更新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)
{
}
我也尝试过在标题中这样做,但是运气不好(我得到了相同的错误)

更新2:
弗雷德·拉森是的!有一个默认构造函数;我忽略了它,因为我认为它与问题无关(我真傻)。删除默认构造函数后,我导致了一个编译器错误,因为该类与std::vector一起使用,后者需要有一个默认构造函数。看起来我必须使用默认构造函数,因此必须使用指针。羞愧。。。还是这样?:)

它们可以初始化。您只需使用成员初始值设定项列表

Foo::Foo(...) : bar1(...), bar2(...), bar3(...)
{
  // Whatever
}
这样初始化所有成员变量是个好主意。否则,除了原始类型,C++将用默认构造函数初始化它们。在大括号中指定它们实际上是重新指定它们,而不是初始化它们


另外,请记住,成员初始值设定项列表指定如何初始化成员变量,而不是顺序。成员按照声明的顺序进行初始化,而不是按照初始化者的顺序进行初始化。

问题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,但它拥有一个内存地址。数组是另一个变量的别名

指针有自己的内存地址,而数组应该被视为共享它引用的变量的地址

对于引用,在初始化和声明它之后,使用它就像使用它引用的变量一样。没有特殊的语法

对于指针,要访问其所在地址的值,必须
取消引用该指针。你可以通过在它前面加一个*来实现

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:

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

../src/textures/VTexture.cpp: In constructor ‘vimrid::textures::VTexture::VTexture()’:
../src/textures/VTexture.cpp:19: error: uninitialized reference member ‘vimrid::textures::VTexture::image’
问题是您没有指定初始值设定项列表。见我对上文问题2的答复。冒号后的所有内容:

class VTexture
{
public:
    VTexture(vimrid::imaging::ImageMatrix &rImage)
      : image(rImage)
    { 
    }
private:
    vimrid::imaging::ImageMatrix ℑ
}
请注意,
bar2
不仅仅在ctor中初始化;它使用作为引用参数传入的
对象初始化。该对象和
bar2
字段将在新
Foo
对象的生命周期内绑定在一起。这通常是一个非常糟糕的想法,因为很难确保两个对象的生命周期能够很好地协调(即,在处理
Foo
对象之前,您永远不会处理传入的bar对象)

这就是为什么人们非常喜欢使用实例变量(如
bar1
)或指向堆上分配的对象的指针(如
bar3

,只使用引用
class VTexture
{
public:
    VTexture(vimrid::imaging::ImageMatrix &rImage)
      : image(rImage)
    { 
    }
private:
    vimrid::imaging::ImageMatrix ℑ
}
class Foo {
public:
    Bar bar1;
    Bar &bar2;
    Bar *bar3;

    // member bar2 must have an initializer in the constructor
    Bar::Bar(Bar& _bar2) : bar1(), bar2(_bar2), bar3(new Bar()) {}

    Bar::~Bar() {delete bar3;}
}
class Foo
{
public:
    Bar bar1; // Here, you create a dependency on the definition of Bar, so the header //file for bar always needs to be included.
    Bar &bar2;
    Bar *bar3; //Here, you create a pointer, and a forward declaration is enough, you don't have to always include the header files for Bar , which is preferred.
}
//header file
class Foo
{
public:
   Foo( void );
   Foo( int& i );
private:
   int& m_int;
};

//source file
static int s_null_Foo_m_i;

Foo::Foo( void ) :
   m_i(s_null_Foo_m_i)
{ }

Foo::Foo( int& i ) :
   m_i(i)
{ }
bool Foo::default_constructed( void )
{
   return &m_i == &s_null_Foo_m_i;
}