C++ C++;在子类内调用基类构造函数

C++ C++;在子类内调用基类构造函数,c++,inheritance,constructor,super,base,C++,Inheritance,Constructor,Super,Base,来自Java的我对调用基类构造函数(或super())有点困惑。 我有两个类:Player(抽象类)和HumanPlayer,后者是Player的子类。 现在,我为玩家创建了一个构造函数,声明如下: Player(string name, list<Point> points); Player(字符串名称、列表点); 现在我正试图实现这样的东西: HumanPlayer() { string name = get name from user... list<

来自Java的我对调用基类构造函数(或
super()
)有点困惑。 我有两个类:Player(抽象类)和HumanPlayer,后者是Player的子类。 现在,我为玩家创建了一个构造函数,声明如下:

Player(string name, list<Point> points);
Player(字符串名称、列表点);
现在我正试图实现这样的东西:

HumanPlayer() {
    string name = get name from user...
    list<Point> points = get points from user...
    ...
    ...
    ...
    super(name, points);
}
HumanPlayer(){
字符串名称=从用户获取名称。。。
列表点=从用户处获取点。。。
...
...
...
超级(名称、点数);
}
<>对C++来说是很新的,它的语法很难用。
关于,初始化派生类的基的唯一方法是在构造函数的初始化列表中。这是在冒号之后,在函数体之前。没有其他正常的方法可以做到这一点

HumanPlayer() :
        Player("...", list_of_points)
{
...
}

如果您确实必须在构造函数的主体中而不是在列表中初始化基类,那么您必须修改代码-例如,通过在基类中引入“initialize()”函数或使用“pimpl惯用法”。

初始化派生类的基类的唯一方法是在构造函数的初始化列表中。这是在冒号之后,在函数体之前。没有其他正常的方法可以做到这一点

HumanPlayer() :
        Player("...", list_of_points)
{
...
}

如果您真的必须在构造函数体中而不是列表中初始化基,那么您必须修改代码-例如,在基类中引入一个“initialize()”函数或使用“pimpl惯用法”。

如果“从用户获取名称…”和“从用户获取点数…”位非常简单,可以实现为简单表达式或函数调用:

HumanPlayer()
   : Player( "get name from user... code",
             "get points from user... code")
{


}
另一方面,如果两个“get”位都是非平凡的,并且相互依赖,那么这将有点复杂。这是一种典型的解决方法的简要概述:

class HelperClass {

public:

    std::string name;
    std::list<Point> points;

    HelperClass()
    {
         // The constructor here will do whatever is needed to initialize name and points
    }
};


// ...

HumanPlayer(const HelperClass &helper=HelperClass())
 : Player(helper.name, helper.points)
{
}
类帮助类{
公众:
std::字符串名;
std::列表点;
助手类()
{
//这里的构造函数将执行初始化名称和点所需的任何操作
}
};
// ...
HumanPlayer(常量HelperClass&helper=HelperClass())
:Player(helper.name、helper.points)
{
}
有些人可能会发现这有点黑客行为:滥用默认参数值来实例化构造函数中使用的对象。但它是有效的。如果使用支持至少C++ 11标准的C++编译器,则可以用不同的方式做得更好。

< P>如果“从用户获得GET…”和“从用户获得点…”位非常简单,并且可以实现为简单表达式或函数调用:

HumanPlayer()
   : Player( "get name from user... code",
             "get points from user... code")
{


}
另一方面,如果两个“get”位都是非平凡的,并且相互依赖,那么这将有点复杂。这是一种典型的解决方法的简要概述:

class HelperClass {

public:

    std::string name;
    std::list<Point> points;

    HelperClass()
    {
         // The constructor here will do whatever is needed to initialize name and points
    }
};


// ...

HumanPlayer(const HelperClass &helper=HelperClass())
 : Player(helper.name, helper.points)
{
}
类帮助类{
公众:
std::字符串名;
std::列表点;
助手类()
{
//这里的构造函数将执行初始化名称和点所需的任何操作
}
};
// ...
HumanPlayer(常量HelperClass&helper=HelperClass())
:Player(helper.name、helper.points)
{
}

有些人可能会发现这有点黑客行为:滥用默认参数值来实例化构造函数中使用的对象。但它是有效的。如果使用支持至少C++ 11标准的C++编译器,那么可以用不同的方式做得更好。它应该会给你正确的语法,我做到了。但它迫使我在实现子构造函数之前调用超级构造函数。不能帮助我完全确定,但你能使用
玩家(姓名、点数)而不是
super()
?不。播放器是抽象的。通常不会在构造函数中从用户收集数据,尤其是在无参数构造函数中。将对象添加到STL容器中时,会发生各种有趣的事情。请检查。它应该会给你正确的语法,我做到了。但它迫使我在实现子构造函数之前调用超级构造函数。不能帮助我完全确定,但你能使用
玩家(姓名、点数)而不是
super()
?不。播放器是抽象的。通常不会在构造函数中从用户收集数据,尤其是在无参数构造函数中。当您将对象添加到STL容器中时,会发生各种有趣的事情。“您必须修改代码,例如,在基类中引入“initialize()”函数或使用“pimpl惯用法”。”。。。您必须修改您的代码-例如,通过在基类中引入“initialize()”函数或使用“pimpl习语”。。。或者修改你的设计。