我有想看看这样一个基类:

class B
{
    // should look like: int I() { return someConst; }
    virtual int I() = 0;
    public B() { something(I()); }
}

当每个对象被构造成被称为是迫使派生类重写I并迫使它的点。这被用来做一些簿记,我需要知道正在构造的对象的类型(但我以其它方式处理的当前对象的基类)。

这不起作用,因为C ++不会让你叫从构造一个抽象的虚函数。

是否有一种方式来获得同样的效果?


根据此链接它似乎是答案有没有办法让我想要的东西。但是它说的是:

  

简短的回答是:没有。基类并不知道什么类它派生的东西,这是一个好东西,太。 [...]也就是说,对象没有正式成为Derived1的实例,直到构造Derived1 :: Derived1开始。

然而,在我来说,我不想知道它的的,但它会的变成的。事实上,我甚至不关心什么,我回去,只要我的用户可以(事后),它映射到一个类。所以,我甚至可以使用像一个返回指针,并摆脱它。

(现在回到读取链接)

有帮助吗?

解决方案

您不能调用虚方法从构造函数(或者更精确地说,你的可以的给他们打电话,但你最终会调用从类目前正在兴建的成员函数)。 ,问题是派生的对象还没有在那个时刻存在。很少有你可以做些什么,呼吁从构造虚拟方法多态是根本不可能的。

您应该重新考虑你的设计 - 传递常量作为参数传递给构造函数,例如:

class B
{
public:
    explicit B(int i)
    {
        something(i);
    }
};

请参阅 C ++ FAQ 了解。如果你的真正的想打电话给施工期间虚函数的阅读本

其他提示

也许使用静态工厂法上的每个派生类型?这是构建异国对象(读:那些具有非常具体的初始化的要求)以通常的方式。在.NET,我已经认识到

class Base
{
  protected Base(int i)
  {
    // do stuff with i
  }
}

class Derived : public Base
{
  private Derived(int i)
    : Base(i)
  {
  }

  public Derived Create()
  {
    return new Derived(someConstantForThisDerivedType);
  }
}

在调用构造函数的基础虚拟方法时一般不赞成,因为你永远是某些特定方法的行为,以及(如别人已经指出的那样)衍生构造将还未被调用。

这不会作为派生类的工作时,执行基类的构造不存在:

class Base
{
public:
    Base()
    {
        // Will call Base::I and not Derived::I because
        // Derived does not yet exist.
        something(I());
    }

    virtual ~Base() = 0
    {
    }

    virtual int I() const = 0;
};

class Derived : public Base
{
public:
    Derived()
     : Base()
    {
    }

    virtual ~Derived()
    {
    }

    virtual int I() const
    {
        return 42;
    }
};

相反,你可以在参数添加到基类的构造函数:

class Base
{
public:
    explicit Base(int i)
    {
        something(i);
    }

    virtual ~Base() = 0
    {
    }
};

class Derived : public Base
{
public:
    Derived()
     : Base(42)
    {
    }

    virtual ~Derived()
    {
    }
};

或者,如果你真的喜欢OOP的,你也可以创建几个其他类的:

class Base
{
public:
    class BaseConstructorArgs
    {
    public:
        virtual ~BaseConstructorArgs() = 0
        {
        }

        virtual int I() const = 0;
    };

    explicit Base(const BaseConstructorArgs& args)
    {
        something(args.I());
    }

    virtual ~Base() = 0
    {
    }
};

class Derived : public Base
{
public:
    class DerivedConstructorArgs : public BaseConstructorArgs
    {
    public:
        virtual ~DerivedConstructorArgs()
        {
        }

        virtual int I() const
        {
            return 42;
        }
    };

    Derived()
     : Base(DerivedConstructorArgs())
    {
    }

    virtual ~Derived()
    {
    }
};

您需要的是两阶段建设。使用通用编程的治愈:添加间接的另一层。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top