C++中的类成员变量可以定义多种数据类型吗?

问题描述 投票:0回答:4

我有一个类定义,我想添加一个成员变量,该变量可以是 2 个不同类之一,具体取决于运行此代码的操作系统。

是否有办法在 C++ 中执行此操作,以便我可以在初始化

operating_system
时根据某些参数或变量为
MyOperatingSystem
成员变量初始化不同的类?

#include <iostream>
#include "Win.h"
#include "Lin.h"

using namespace std;

typedef int os_type;
enum {Win, Lin};

class MyOperatingSystem {
  public:
    MyOperatingSystem(int ver, string n, os_type os);
  private:           
    int version;
    string name;
    // operating_system // want this to be either (Windows win | Linux lin)

};

// constructor
MyOperatingSystem::MyOperatingSystem(int ver, string n, os_type os){
    version = ver;
    name = n;
    if (os == Win){
        // operating system = Windows(int i);
    }
    else{
        // operating system = Linux(int i)
    }
}

Win.h和Lin.h如下

Win.h:

#include <windows.h>
class Windows{
    public:
        Windows(int i){
            integer = i;
            mystring = "WinString";
        }
    private:
        int integer;
        LPCWSTR mystring;
};

林.h:

#include <termios.h>
class Linux{
    public:
        Linux(int i){
            integer = i;
            mystring = "LinString";
        }
    private:
        int integer;
        cc_t* mystring;
};
c++ class operating-system
4个回答
6
投票

我建议做出编译时决定。

示例:

#pragma once // MyOperatingSystem.h

class IOperatingSystem {
public:
    virtual ~IOperatingSystem() = default;

    // misc operations:
    virtual foo() = 0;
};

#ifdef _WIN32
#include "internal/Win.h" // in here MyOperatingSystem  implements  IOperatingSystem 
#else
#include "internal/Lin.h" // in here MyOperatingSystem  implements  IOperatingSystem 
#endif

您不一定需要

virtual
,但在设计时它会有所帮助,以确保两个实现都遵循相同的接口。


1
投票

最明显的解决方案是拥有一个具有公共接口的

OperatingSystem
基类,并从中派生
Win
Linux


0
投票

操作系统是编译时的事情,因此您可以使用模板参数

template <ostype os> class MyOperatingSystem ...

然后您可以使用

if constexpr
检查您拥有哪些操作系统并在类中包含不同的代码。
Windows
Linux
类可能应该有一个共同的基类,然后大多数差异将通过虚拟方法来解决。所以
if constexpr (os == Win) ...
应该是例外。

另一种方法是依赖项插入:

MyOperatingSystem(int ver, string n, Os & os);

其中

Os
Windows
Linux
的公共基类。

或者再说一遍,因为这是编译时的事情:

template <typename Os> class MyOperatingSystem : public Os { ... }
template <typename Os> class MyOperatingSystem  { ... Os os; }

在这种情况下,您甚至不需要公共基类(但它有助于确保公共接口)。

Windows
Linux
都只需遵循一个通用接口,例如定义
os_type
。如果
Os::os_type
是 constexpr,您可以再次使用
if constexpr
。但我认为 Os 类的重点是封装所有操作系统特定的代码,因此如果使用的话,这种情况应该很少见。

请注意,使用

Os
模板方式,
MyOperatingSystem
类是(或具有)具体的
Windows
Linux
类。因此,所有虚拟函数调用都被具体调用所取代。所以没有开销。早期的情况有一个指向基类的指针或引用,并且需要进行虚拟方法调用。


-3
投票
std::variant<Windows, Linux> operating_system;

std::variant
是一个求和类型——它是类型列表中的类型之一。

作为一个副作用,它带有它本身的类型——所以

os_type
变量存储在它旁边是多余的。

© www.soinside.com 2019 - 2024. All rights reserved.