【问题标题】:Reusable constructors C++可重用的构造函数 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++ 中是否有任何语法允许您这样做?

【问题讨论】:

    标签: c++ oop constructor reusability


    【解决方案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@,这可能没有意义。
        猜你喜欢
        • 1970-01-01
        • 2011-07-30
        • 2010-09-25
        • 1970-01-01
        • 1970-01-01
        • 2018-10-17
        • 2016-01-02
        • 2020-01-01
        • 1970-01-01
        相关资源
        最近更新 更多