C++ 我必须为我的C+使用指针吗+;类字段?
在阅读了上的一个问题后,我决定对我的类字段使用引用而不是指针。然而,这似乎是不可能的,因为它们不能被声明为未初始化(对吗?) 在我现在正在处理的特定场景中,我不想使用普通变量(顺便问一下,它们的正确术语是什么?),因为当我声明它们时,它们会自动初始化 在我的代码片段中,bar1会自动使用默认构造函数实例化(这不是我想要的),&bar2会导致编译器错误,因为您不能使用未初始化的引用(正确吗?),而*bar3也很高兴,因为指针可以声明为未初始化(顺便问一下,将其设置为NULL是否是最佳做法?) 看起来我必须在这个场景中使用指针,这是真的吗?另外,使用变量的最佳方式是什么?->语法有点麻烦。。。运气不好?等等呢?这是否相关 更新1: 在尝试在类中实现引用变量字段并在构造函数中初始化它之后,为什么会收到以下错误C++ 我必须为我的C+使用指针吗+;类字段?,c++,pointers,reference,C++,Pointers,Reference,在阅读了上的一个问题后,我决定对我的类字段使用引用而不是指针。然而,这似乎是不可能的,因为它们不能被声明为未初始化(对吗?) 在我现在正在处理的特定场景中,我不想使用普通变量(顺便问一下,它们的正确术语是什么?),因为当我声明它们时,它们会自动初始化 在我的代码片段中,bar1会自动使用默认构造函数实例化(这不是我想要的),&bar2会导致编译器错误,因为您不能使用未初始化的引用(正确吗?),而*bar3也很高兴,因为指针可以声明为未初始化(顺便问一下,将其设置为NULL是否是最佳做法?) 看起
../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;
}