开发者

Possible to eliminate this base-class constructor?

开发者 https://www.devze.com 2023-04-13 01:26 出处:网络
Is there any way to eliminate the explicit constructor 开发者_运维知识库call in Foo and somehow have Bar::len assigned to the size of any of Bar\'s sub-classes?

Is there any way to eliminate the explicit constructor 开发者_运维知识库call in Foo and somehow have Bar::len assigned to the size of any of Bar's sub-classes?

class Bar
{
    size_t len_;

    Bar(size_t len) : len_(len) { }
};

class Foo : public Bar
{    
    Foo() : Bar(sizeof(Foo)) { }
};


You could use a "curiously recursive template" to inform the base class of the derived class's type:

template <typename Derived>
class Bar
{
    size_t len_;
protected:
    Bar() : len_(sizeof(Derived)) {}
};

class Foo : public Bar<Foo>
{
};


virtual inheritance might do what you want:

#include <iostream>

class Bar
{
    size_t len_;
public:
    Bar(size_t len) : len_(len) {std::cout << len << '\n';}
};

class Foo : virtual public Bar //virtual inheritance
{    
    size_t foo_bigger_than_bar;
public:
    Foo() : Bar(sizeof(Foo)) { } //Bar only called if Foo is most derived
};

class Derived2: public Foo
{    
    size_t derived2_bigger_than_foo;
public:
    Derived2() : Bar(sizeof(Derived2)), Foo() { }
    // since Foo virtually derives from Bar, we have (get) to 
    // initialize Bar ourselves.
};

int main() {
    Foo f;
    std::cout << '\n';
    Derived2 d;
}

A virtual base class is only initialized by the most derived class. Eg, when creating a Derived2, Foo's constructor will not construct the Bar object, since Derived2 already constructed it. This is key for diamond inheritance, like std::fstream.
Demo here: http://codepad.org/HUlLB4Uq

0

精彩评论

暂无评论...
验证码 换一张
取 消