0

我有这段代码用于在 C++ 中调用父初始化程序。

#include <iostream>

using namespace std;

class A
{
public:
    A(const string& a) {}
};

class B : public A
{
public:
    B(const string& b) : A(b) {}
};

我想我可以用这样的父初始化器来装饰一点。

B(const string& b) : A(b + "!!") {}

那么,当我需要一些决策逻辑来设置父初始值设定项时呢?我试过这个,但我收到错误消息。

B(const string& b) {
    if (...) {
        A(b + "x");
    } else {
        A(b + "y");
    }
}

>> ERROR 

hier.cpp: In constructor 'B::B(const string&)':
hier.cpp:16:2: error: no matching function for call to 'A::A()'
4

5 回答 5

3

您在初始化列表中对其进行编码:

B(const string& b) : A(b + ((...) ? "x" : "y")) {}

如果“决策逻辑”变得更加复杂,您可以将其分解为一个单独的函数(通常是一个私有静态成员)。

于 2013-06-14T16:06:27.357 回答
2

如果您要执行复杂的逻辑,最好将其放在单独的函数中:

std::string modify(const std::string &b) {
    if (...) {
        return b + "x";
    } else {
        return b + "y";
    }
}

然后您可以在初始化列表中使用该函数:

B(const string& b) : A(modify(b)) {}
于 2013-06-14T16:14:02.677 回答
1

您可以在基类的构造函数中放置一个静态私有方法,如下所示:

class B : public A
{
public:
    B(const string& b) : A(initval(b)){}
private:
    static string initval(const string& b) {
        if (...)
            return b + "x";
        else
            return b + "y";
    }
};
于 2013-06-14T16:15:27.127 回答
1

除了sth的回答,我也会把modify函数设为B的静态方法。

std::string B::modify(const std::string &b) {
    if (...) {
        return b + "x";
    } else {
        return b + "y";
    }
}

在类定义中:

static std::string B::modify(const std::string &b)

然后,使用它:

B(const string& b) : A(B::modify(b)) {}

这样做的原因是它将被完全封装在 B 内部,而不是作为外部的单独函数。它将更加面向对象。

于 2013-06-14T16:33:57.470 回答
0

只要您调用相同的构造函数(为初始化程序使用相同的签名),您就可以使用 Casey 的答案。但是,如果你想做这样的事情:

B(const string& b) {
    if (...) {
        A(b + "x");
    } else {
        A(foo, bar);
    }
}

那么你注定要失败。C++ 中没有这样的东西。解决它的唯一方法是调用默认构造函数,然后使用专门的成员函数(通常称为 init() 或类似的东西)进行初始化。当您有一堆不同的构造函数应该通过相互调用来实现时,这与您需要的技术相同,遗憾的是,这在 C++ 中是被禁止的。这两个问题在 Objective-C 这样漂亮的语言中都不存在。

于 2013-06-14T16:09:53.100 回答