const_cast在c ++中失败

时间:2012-08-08 12:09:15

标签: c++ const-cast

CallingClass::CallingFunc()
{
    SomeClass obj;
    obj.Construct(*Singleton::GetInstance()); // passing the listener
    // Singleton::GetInstance() returns a static pointer.
    //Singleton is derived from IListener
}

SomeClass::Construct(const IListener &listener)
{
    IListener* pListener = const_cast<IListener*>(&listener);
}

const_cast pListener为空后。 是否有可能进行类型转换?

由于

3 个答案:

答案 0 :(得分:10)

让我看看。你有两阶段初始化,一个Singleton,抛弃const你要取消引用一个对象只是为了再次获取它的地址?一个迷路的NULL指针是你关心的最少,我的朋友。

扔掉它并从头开始再写。并首先拿起一本C ++书。

您知道,const_cast除非传递了空指针,否则无法生成空指针。 GetInstance()必须返回NULL才能产生此行为,一旦您取消引用它就会正式为UB。

答案 1 :(得分:1)

const_cast基本上是编译器忽略某些东西的指令。应避免使用它,因为您正在覆盖编译器保护,并且当您编写试图更新只读内存的内容时,它可能导致崩溃。

但是,它实际上并不会导致生成任何代码。

因此,如果这样:

IListener* pListener = const_cast<IListener*>(&listener);

导致pListener为NULL,然后&amp; listener为NULL,这是不可能的(或者你为你的单例返回一个空引用,或者你从问题描述中遗漏了一些东西)。

说完我同意DeadMG的回答。

应避免创建空对象并对其执行Init(两阶段构造)。正确创建的对象应该是有效的,如果你有一个Init方法,它就不是。

应避免从任何事物中删除常量 - 它极有可能产生令人惊讶的行为。

该代码中的去重新引用量会给任何人带来麻烦。

答案 2 :(得分:0)

两个问题:

  1. 你想在这里做些什么?
  2. 您对代码有多少控制权? (即你能改变什么?)
  3. 不希望自己不仁慈,我会诚实地说,重新开始可能会更好。我对这段代码有几个问题:

    首先,Singleton模式应确保只创建一个特定对象,因此它通常由指针,引用或其衍生物(即boost共享指针等)返回。它不一定是const而是它在这里的事实表明作者并不打算以非常规的方式使用它。

    其次,您通过引用将此对象传递给函数。没必要。这是单例模式的主要特征(和缺点)之一:您可以从任何地方访问它。所以你可以轻松地写一下:

    SomeClass::Construct()
    {
        IListener* pListener = const_cast<IListener*>(*Singleton::GetInstance());
    }
    

    虽然这对你来说仍然没有帮助。它做的一件事是让你的界面更清晰。你知道,当你写SomeClass::Construct(const IListener&listener)时,任何阅读你的人都可以合理地暗示listener在函数中被视为const并使用const_cast,你已经打破了隐含合同。 这是一个非常好的理由,您不应该使用const_cast - 至少在这种情况下不会这样做。

    您需要问自己的基本问题是,当您的IListener是const时,为什么需要在Construct内以非常规方式使用它?单例不应该返回const对象,否则你的函数不应该需要非const。

    这是一个设计问题,您需要在采取任何进一步措施之前进行整理。