已关闭。此问题需要更多focused。目前不接受回答。
**要改进此问题吗?**更新此问题,使其仅针对editing this post的一个问题。
4天前关闭。
Improve this question的
我对c++还很陌生,想了解一下创建成员变量的思想过程。例如,如果我浏览一个头文件,我看到一些成员变量被声明为指针,而另一些则被声明为引用。
// in foo.h
class Foo {
private:
A* const a;
B& b;
std::unique_ptr<C> c;
};
字符串
声明与声明之间有什么区别(这是正确的术语吗?)a
,b
& c
是这样的吗?我知道a
是const pointer
,即,它指向某个存储器,该存储器中保存着A
类型的对象& b
是一个引用。c
是一个unique_ptr
,它持有一个C
类型的对象。但是我不明白为什么你要这样声明一些东西。我来自Java/Python背景,所以请忍受我的困惑。
2条答案
按热度按时间lh80um4z1#
字符串
上面是对B对象的引用。作为引用,它永远不能为NULL,并且不能重新定向到引用与最初初始化引用的对象不同的对象。您也可以通过用于“普通”成员变量的相同语法访问它因为它是不可改变的,它的存在意味着你必须通过每个构造函数中的初始化器将它设置为,否则你会得到一个编译时错误。
型
上面是一个指向只读A对象的指针.或者它可以被设置为NULL,在这种情况下,它根本没有指向任何有效的对象。由于它的值可以在运行时更改,因此它不需要由对象的构造函数初始化(尽管最好至少将其初始化为NULL,这样如果您的任何代码试图在设置它之前访问它,你会更有可能得到一个明显的/可重复的崩溃)
型
这与
C * c;
类似,但更好(假设您的对象旨在“拥有”C对象),因为它显式地指示所有权关系,并将在删除unique_ptr
时自动删除指向的C对象。bqujaahr2#
我想了解以这种方式创建成员变量背后的思想过程
注意这与成员变量无关--同样的约束也适用于 any 作用域中的指针/引用/智能指针。也就是说,它们可能是全局变量、函数中的自动局部变量、静态全局变量或静态局部变量等。
这其中很大一部分是为了让人类能够理解代码。通常的约定是:
a
是一个非拥有指针,b
是对单个对象的不可变引用(非拥有),只要该引用存在,该对象就必须存在,c
是一个拥有指针,用于管理指向对象的生存期。在非拥有指针和引用之间的选择归结为如何使用指针/引用。如果使用的API/库已经通过对象指针而不是引用传递某些对象,那么这就是你要做的。如果你需要改变引用的对象,必须使用指针。
引用明确表示只有一个对象(而不是一个数组,或者
nullptr
),并且它是不可变的。这意味着一旦引用绑定到一个对象,只要引用存在,它就将保持绑定到该对象。在C中,空引用是未定义的行为,所以你永远不应该期望引用是空的。事实上,任何像
Obj& ref; ... if (&ref != nullptr) { do_something(); }
这样的测试都会减少到if (true) { do_something(); }
。引用(对人类)明确声明类
Foo
要求b
中的对象在Foo
的整个生命周期中都存在。由于引用是不可变的,唯一设置它的机会是在构造函数中。构造之后,它引用的任何对象都将保留,直到Foo
示例被销毁。结束一个引用对象的生命是一种未定义的行为。“未定义的行为”是一个口语术语,意思是“如果你这样做,编译器就可以对你的代码做任何事情,除非编译器文档中另有说明”。在C标准中未定义的行为可能仍然是实现定义的,但是如果你依赖于它,你正在使你的代码不可移植,并且依赖于特定的编译器实现。这有时是不可避免的,但通常不是一件好事。