指针是否可以指向const空类或非const类?

时间:2013-08-01 19:23:15

标签: c++ pointers

据推测不是。这是我的用例:

我有两个班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对象,但这让我感觉很糟糕。

是否有方法或模式来解决我的问题?

3 个答案:

答案 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,包装器将为你提供有意义的东西。