如何在c++中实现二次构造函数

How can I do second-like constructor in c++?

本文关键字:二次 构造函数 实现 c++      更新时间:2023-10-16

我有一个class Aclass B, B这里是A的子类:

class A {
 public:
  A(int a) : obj(a) {}
  void init() {
    if(magic_str == "hello") {
      // do init c
      c = 7;
    }
  }
 private:
   int obj;
   int c;
 protected:
   string magic_str;
};
class B : public A {
 public:
  B(int a, double _b) : A(a), b(_b){}
  void set_magic_str() {
    magic_str = "hello";
  }
 private:
   double b;
};

上面,A中的init函数必须在A中构造,但必须在magic_str初始化之后调用。magic_str必须在class B中初始化,因为有一些自定义逻辑。

如何在A中强制B调用init ?

总而言之,我想把A中的构造函数代码分成两部分,在这两部分之间,一些用户定义的行为必须在其子类B中初始化。

一种方法是将魔法字符串作为构造函数传递给A的构造函数,并在构造函数中调用init。

class A {
 public:
  A(int a, string m) : obj(a), magic_str(m) 
  { 
      init();
  }
  void init() {
    if(magic_str == "hello") {
      // do init c
      c = 7;
    }
  }
 private:
   int obj;
   int c;
 protected:
   string magic_str;
};
class B : public A {
 public:
  B(int a, double _b) : A(a,get_magic_str()), b(_b){}
  static string get_magic_str() {
    return "hello";
  }
 private:
   double b;
};

另一种方法是使用构建器模式,并让它处理您希望创建对象的复杂方式:

class A {
 public:
  A(int a) : obj(a) {}
  void init() {
    if(magic_str == "hello") {
      // do init c
      c = 7;
    }
  }
 private:
   int obj;
   int c;
 protected:
   string magic_str;
};
class B : public A {
 public:
  static B create (int a, double _b) // <-- only allow instances to be created via this function
  {
      B b = B(a, _b);
      b.init();
      return b;
  }
  void set_magic_str() {
    magic_str = "hello";
  }
 private:
  B(int a, double _b) : A(a), b(_b){} //maybe protected
   double b;
};

由于init是a的非私有成员函数,B从a派生而来,可以调用init。在设置magic_string之后调用它。构造函数。

    A::init();

否则,更改A的构造函数,并在b中使用它。

    A(int a, string s)
    B(int a, double _b): A (a, magic_str)...

我会将逻辑更改为如下内容:

class A {
public:
    A(int a) : obj(a), c(0) {}
protected:
    void set_magic_str(const std::string& s) {
        magic_str = s;
        if (magic_str == "hello") {
            // do init c
            c = 7;
        }
    }
private:
    int obj;
    int c;
    std::string magic_str;
};
class B : public A {
public:
    B(int a, double _b) : A(a), b(_b){}
    void set_magic_str() {
        A::set_magic_str("hello");
    }
private:
    double b;
};