我有一个基类和一个派生类。派生类具有一些附加功能,用户可以在他们正在访问的类之间切换。
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
中分配派生类。实际实现几乎肯定会使用运算符new
和delete
的动态分配。
可以将函数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*
指针并指向base
或derived
。