如何为父类和派生类使用一个变量

时间:2019-12-11 23:37:47

标签: c++ polymorphism

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

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 ++中有没有办法做到这一点?另外,有没有办法我可以在valid_operations中将DerivedClass声明为{"!", "q"} + BaseClass.valid_operations

2 个答案:

答案 0 :(得分:1)

您不能使用数组变量来执行此操作,但是如果选择向量,则可以在基中声明它,然后在受保护的构造函数中进行初始化,如下所示:

ControlService()

请注意,该示例未使用一个派生类,而是建立了一个自己不具有任何操作的基础,并依靠子类在构造函数中提供操作列表。

还要注意,该实现使用自动存储功能在auto showError = []() { DWORD err = GetLastError(); qDebug() << "Restart PostgreSQL service failed. Error: " << err << "\n"; }; SERVICE_STATUS Status; SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (!SCManager) { showError(); return; } SC_HANDLE SHandle = OpenService(SCManager, L"postgres", SERVICE_STOP | SERVICE_START | SERVICE_QUERY_STATUS); if (!SHandle) { showError(); CloseServiceHandle(SCManager); return; } if (!QueryServiceStatus(SHandle, &Status)) { showError(); CloseServiceHandle(SHandle); CloseServiceHandle(SCManager); return; } if (Status.dwCurrentState != SERVICE_STOPPED) { qDebug() << "Stopping PostgreSQL service...\n"; if (!ControlService(SHandle, SERVICE_CONTROL_STOP, &Status)) { showError(); CloseServiceHandle(SHandle); CloseServiceHandle(SCManager); return; } DWORD dwStartTime = GetTickCount(); DWORD dwTimeout = 30000; // 30-second time-out DWORD dwWaitTime; while (Status.dwCurrentState == SERVICE_STOP_PENDING) { qDebug() << "Waiting for PostgreSQL service to stop...\n"; dwWaitTime = Status.dwWaitHint / 10; if (dwWaitTime < 1000) dwWaitTime = 1000; else if (dwWaitTime > 10000) dwWaitTime = 10000; Sleep(dwWaitTime); if (!QueryServiceStatus(SHandle, &Status)) { showError(); CloseServiceHandle(SHandle); CloseServiceHandle(SCManager); return; } if (Status.dwCurrentState != SERVICE_STOP_PENDING) break; if (GetTickCount() - dwStartTime > dwTimeout) { qDebug() << "Stop of PostgreSQL service timed out.\n"; CloseServiceHandle(SHandle); CloseServiceHandle(SCManager); return; } } if (Status.dwCurrentState != SERVICE_STOPPED) { qDebug() << "Restart PostgreSQL service failed. Service did not stop.\n"; CloseServiceHandle(SHandle); CloseServiceHandle(SCManager); return; } qDebug() << "PostgreSQL service stopped successfully.\n"; } if (!StartService(SHandle, 0, NULL)) showError(); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); 中分配派生类,以方便使用。实际的实现几乎可以肯定会使用带有运算符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的动态分配。

答案 1 :(得分:1)

您可以在基类中将函数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