如何将一个变量用于父类和派生类



我有一个基类和一个派生类。派生类具有一些附加功能,用户可以在他们正在访问的类之间切换。

class BaseClass {
private:
string valid_operations[2] = {"%", "#"};
};
class DerivedClass : BaseClass {
private:
string valid_operations[4] = {"!", "q", "%", "#"};
};

我试图做的是实例化单个对象,并让用户能够在这两个对象之间互换切换。

例如:

BaseClass obj;
string input;
while (true) {
cin >> input;
if (input == "switch")
obj = DerivedClass();
else
obj.apply_action(input);
}

有没有办法在C++做到这一点?另外,有没有办法在DerivedClass中声明valid_operations{"!", "q"} + BaseClass.valid_operations

你不能用数组变量来做到这一点,但是如果你选择向量,你可以在基中声明它,并在受保护的构造函数中初始化,如下所示:

class BaseClass {
private:
std::vector<string> valid_operations;
protected:
BaseClass(std::vector<string> vo) : valid_operations(vo) {}
public:
void ShowValidOperations() {
for (string op : valid_operations) {
std::cout << op << " ";
}
std::cout << std::endl;
}
};
class OptionOneDerived : public BaseClass {
public:
OptionOneDerived() : BaseClass({"%", "#"}) {
}
};
class OptionTwoDerived : public BaseClass {
public:
OptionTwoDerived() : BaseClass({"!", "q", "%", "#"}) {
}
};
int main() {
BaseClass *b;
OptionOneDerived a;
b = &a;
b->ShowValidOperations();
OptionTwoDerived c;
b = &c;
b->ShowValidOperations();
return 0;
}

请注意,该示例不是使用一个派生类,而是设置一个没有自己的操作的基,并依赖于子类在构造函数中提供操作列表。

另请注意,为了实现方便起见,该实现使用自动存储在main中分配派生类。实际实现几乎肯定会使用运算符newdelete的动态分配。

可以将函数apply_action()声明为基类中的虚函数。然后,可以在派生类中重写该函数并使用多态性。

class BaseClass {
public:
BaseClass(std::set<std::string> actions) : valid_operations(std::move(actions)) {}
virtual void apply_action(std::string action)
{
if (IsValid(action))
{
//Do stuff
}
}
protected:
bool IsValid(const std::string& action)
{
return valid_operations.find(action) != std::end(valid_operations);
}
private:
std::set<std::string> valid_operations;
};
class DerivedClass : public BaseClass {
public:
DerivedClass(std::set<std::string> actions) : BaseClass(actions) {}
virtual void apply_action(std::string action) override 
{
if (IsValid(action))
{
//Do stuff
}
}
};

main()函数中或要使用这些类的任何位置,您可以创建如下实例:

BaseClass base({ "%", "#" });
DerivedClass derived({ "!", "q", "%", "#" });

使用一个BaseClass*指针,您可以切换为使用这些对象之一。这就是多态性的工作原理:相同的名称,但根据使用的实际对象而具有不同的行为。使用BaseClass*指针并指向basederived

最新更新