开发者

Reusable constructors C++

开发者 https://www.devze.com 2023-04-11 14:40 出处:网络
One of the corner stones of OOP is reusing code instead of repeat it over and over. Thus, your projects shorten and get more readable.

One of the corner stones of OOP is reusing code instead of repeat it over and over. Thus, your projects shorten and get more readable.

C++ gives you all the tools you need to reuse methods instead of repeating the code. Although when it comes to constructors I do not know how to reuse them.

I am not talking of heritage or how to send a message to the father. I am talking about reusing the constructor of the class itself.

The analogy in JAVA is something like this:

public Foo() {
    this(0,0,0);//Not needed in this case, just to clarify
}

public Foo(Foo f){
    this(f.getA(), f.getB(), f.getC());
}

public Foo(int a, int b, int c) {
    this.a = a;
    this.b = b;
    this.c = c;
}

My question is, is there any syntaxis in C+开发者_如何学运维+ that allows you to do so?


C++11 has added constructor delegation and constructor inheritance.

To inherit constructors, a using-declaration is required:

class Base { ... };

class Derived : public Base
{
    using Base::Base;
};

To delegate, use the ctor-initializer, but specify another constructor in the same class, instead of any subobjects (all base and member subobjects will be initialized by the constructor delegated to):

class Another : public Base
{
    int member;
    Another(int x)
        : Base(), member(x) // non-delegating constructor initializes sub-objects
    {}


    Another(void)
        : Another(5) // delegates -- other constructor takes care of Base and member
    {}
};

And perfect forwarding can also come in handy.


Others already answered about C++11, but for C++03 there's a possible workaround: using a base class with needed constructor(s).

struct foo_base {
    foo_base(int a, int b, int c) : a(a), b(b), c(c) { }
    int a, b, c;
};

struct foo : foo_base {
    foo() : foo_base(0, 0, 0) { }
    foo(const foo& other) : foo_base(other.a, other.b, other.c) { }
    foo(int a, int b, int c) : foo_base(a, b, c) { }
};

Of course, you need to consider whether it's worth the boilerplate for your purposes.


The generally accepted soultion for current compilers is to do this:

class Bar{
pubilc:    
Foo() {
   init(0,0,0);
}

Foo(const Foo &f){
  init(f.getA(), f.getB(), f.getC());
}

Foo(int a, int b, int c) {
  init(a,b,c);
}

private:

void init(int a, int b, int c){
  this->a = a;
  this->b = b;
  this->c = c;
}
};

While this may seem like over kill in this example, that is only because of the simplicity of the example. In a real world application this would actually bring benefits in terms of reduction of repeated code.


OK C++11 covers what you need.

But your simple case has an easy solution:

/* This one is covered by providing default parameters see below.
public Foo() {
    this(0,0,0);//Not needed in this case, just to clarify
}

 This is done automatically by the compiler.
 You do not need to write any code for this:
public Foo(Foo f){
    this(f.getA(), f.getB(), f.getC());
}
The compiler generated version actually looks like this:
public Foo(Foo const& f)
    : a(f.a)
    , b(f.b)
    , c(f.c)
{}



*/

// Now you can use all three methods and they work fine:
public Foo(int a = 0, int b = 0, int c = 0)
    : a(a)
    , b(b)
    , c(c)
{}

F   f1;        // default construct no parameters: uses the three parameter version
F   f2(f1);    // Copy constructed. Generated by the compiler.
F   f3(1,2,3); // Nomal constructor
0

精彩评论

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

关注公众号