可重用的构造函数 C++

Posted

技术标签:

【中文标题】可重用的构造函数 C++【英文标题】:Reusable constructors C++ 【发布时间】:2011-12-01 20:01:23 【问题描述】:

OOP 的基石之一是重用代码,而不是一遍又一遍地重复。因此,您的项目会缩短并变得更具可读性。

C++ 为您提供了重用方法而不是重复代码所需的所有工具。虽然当涉及到构造函数时,我不知道如何重用它们。

不是谈论遗产或如何向父亲传达信息。我说的是重用类本身的构造函数。

JAVA中的类比是这样的:

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;

我的问题是,C++ 中是否有任何语法允许您这样做?

【问题讨论】:

【参考方案1】:

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

要继承构造函数,需要using-declaration

class Base  ... ;

class Derived : public Base

    using Base::Base;
;

要委托,请使用 ctor-initializer,但在同一个类中指定另一个构造函数,而不是任何子对象(所有基子对象和成员子对象都将由委托给的构造函数初始化):

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
    
;

而且完美转发也能派上用场。

【讨论】:

【参考方案2】:

其他人已经回答了有关 C++11 的问题,但对于 C++03,有一个可能的解决方法:使用带有所需构造函数的基类。

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)  
;

当然,您需要考虑是否值得为您的目的使用样板。

【讨论】:

【参考方案3】:

目前编译器普遍接受的建议是这样做:

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;

;

虽然在这个例子中这看起来有点过头了,但这只是因为例子很简单。在实际应用中,这实际上会在减少重复代码方面带来好处。

【讨论】:

对不起,java 和 c++ 有时对我来说是模糊的。我编辑了我的帖子,现在假设你有有效的 getA()、getB()、getC() 函数,它现在完全使用有效的 c++。 this.a 无效,复制构造函数应将 const 引用作为参数。 糟糕,抱歉。感谢您收看 Cat Plus Plus。下次继续修复它。 @Kurtis Nusbaum:即使你有有效的 getA() 你会使用它吗?您可以完全访问同一类型的另一个对象的所有成员(假设您相信自己可以编写好的代码)。 成员应该在 ctor-initializer 列表中分配,一方面这是设置const 成员的唯一方法。【参考方案4】:

OK C++11 涵盖了你所需要的。

但是您的简单案例有一个简单的解决方案:

/* 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

【讨论】:

如果不是all,我通常反对使用默认值作为参数987654322@,这可能没有意义。

以上是关于可重用的构造函数 C++的主要内容,如果未能解决你的问题,请参考以下文章

C++:在派生类构造函数中调用基类赋值运算符的错误形式?

C++ 构造函数 & 析构函数

c++类的构造函数

C++ Primer Plus学习:第十章

构造函数重载时重用代码? [复制]

c++类的构造函数不显式声明会自动生成吗