据推测不是。这是我的用例:
我有两个班A&乙
class A
{
B *b_;
};
class B
{
public:
B(): b_string_("") {};
private:
std::string b_string_;
};
我希望b_始终指向B对象。我希望b_指向一个“空”B对象而不是nullptr,这样我总是可以以定义的方式取消引用* b_以得到一个空的b _-> b_string。所以我想我会创建一个全局的“null B对象”:const B null_b
。但我不能(自然地)使用这个A ctor:
A(): b_(&null_b) {};
因为b_不能指向const变量。如果不是“空B对象”,则b_需要指向可变B对象。
使全局非const解决问题,但我想保护const,所以我可以保证“null对象”永远不会改变。
FWIW,这涉及一个大项目,其中b_指向另一个类中B对象的向量。我可以在那个向量中添加一个空的B对象,但这让我感觉很糟糕。
是否有方法或模式来解决我的问题?
答案 0 :(得分:5)
不是保存指向B
对象的指针,而是使用虚方法创建基类并存储指向它的指针。从中导出B
类和Null_B
类,但不要让Null_B
上的方法进行修改。现在,即使您的Null_B
对象不是const
,也不再重要。
作为额外的保护层,您可以尝试修改null_b
对象抛出异常,以便检测并发现逻辑错误。
答案 1 :(得分:3)
在const
对象上不能有“非常量”指针点。不幸的是,使用const_cast
删除对象的const
- 将意味着稍后某些代码可以尝试修改对象。 (请注意,除非原始对象是非const,否则抛弃const
是未定义的行为,因此从技术上讲,允许编译器生成在发生这种情况时崩溃的代码。不幸的是,很多情况下,它不会崩溃该对象比const char *
或const int []
更复杂 - 允许代码在覆盖您不想编写的对象后快乐地继续。)
但是,由于B
类的b_string_
成员是私有的,因此没有外部对象可以触及它,因此您可以确保b_string_
的所有使用都是通过虚拟完成的函数(或多个虚函数),然后从B
派生另一个类,其中,当代码试图修改b_string
时,虚拟函数和“抱歉,你不能这样做”在派生对象中。
答案 2 :(得分:1)
好吧,也许它完全不合适,但是......你可以使用B的实例而不是A中的B指针吗?这将解决潜在的nullptr解除引用问题。
编辑好吧,如果B太大,那么你可以在它周围创建一个轻量级的包装器,并将该包装器的实例存储在A中。如果B是nullptr,包装器将为你提供有意义的东西。