如何声明可能是两个 class 之一的 class 成员
How to declare a class member that may be one of two classes
我正在处理一个很大程度上不是我创建的项目,但我的任务是向其中添加一些功能。目前,有一个设备class有一个成员变量,负责存储有关存储位置的信息,设置如下:
device.hpp
class device {
public:
// Stuff
private:
// Stuff
StorageInfo storage_info_;
// Even more stuff
}
StorageInfo.hpp
class StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
我的任务是实施不同的存储选项,以便可以在两者之间切换。这个新存储选项具有的信息功能与初始存储选项相同,但检索该信息的实现方式却大不相同。为了保持整洁并在未来几年更容易维护此应用程序,确实需要在两个不同的文件中定义它们。但是,这会在 device.cpp
内部以及调用 StorageInfo class 的每个其他文件中产生问题。如果我创建两个单独的成员变量,一个用于每种类型的存储,那么我不仅需要插入一百万个不同的 ifelse 语句,而且我有可能 运行 进入构造函数中的初始化问题。相反,我想做的是拥有一个成员变量,它有可能保存任一存储选项 class。像这样:
StorageInfoA.hpp
class StorageInfoA: StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
StorageInfoB.hpp
class StorageInfoB: StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
device.hpp
class device {
public:
// Stuff
private:
// Stuff
StorageInfo storage_info_;
// Even more stuff
}
device.cpp
//Somewhere in the constructor of device.cpp
if(save_to_cache){
storage_info_ = StorageInfoA();
} else {
storage_info_ = StorageInfoB();
}
// Then, these types of calls would return the correct implementation without further ifelse calls
storage_info_.updateStorageInfo();
但是,我知道 cpp 绝对讨厌任何带有动态类型的东西,所以我真的不知道如何实现它。这种事情甚至可能吗?如果没有,有没有人知道可以使用 cpp 的打字规则实现此功能的类似方法?
你的方向是对的,但你必须学会如何使用多态性。在您的示例中,您需要进行以下修复:
在基础class中,将所有函数虚化,并添加一个虚函数
析构函数:
class StorageInfo {
public:
virtual ~StorageInfo(){}
virtual void initializeStorage();
//...
};
继承你的财产public:
class StorageInfoA: public StorageInfo {
不是按值保存 StorageInfo
,而是将其保存在智能指针中:
class device {
private:
std::unique_ptr<StorageInfo> storage_info_;
};
device
构造函数看起来像
//Somewhere in the constructor of device.cpp
if(save_to_cache){
storage_info_ = std::make_unique<StorageInfoA>();
} else {
storage_info_ = std::make_unique<StorageInfoB>();
}
最后,您将像普通指针一样使用它:
storage_info_->updateStorageInfo();
我正在处理一个很大程度上不是我创建的项目,但我的任务是向其中添加一些功能。目前,有一个设备class有一个成员变量,负责存储有关存储位置的信息,设置如下:
device.hpp
class device {
public:
// Stuff
private:
// Stuff
StorageInfo storage_info_;
// Even more stuff
}
StorageInfo.hpp
class StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
我的任务是实施不同的存储选项,以便可以在两者之间切换。这个新存储选项具有的信息功能与初始存储选项相同,但检索该信息的实现方式却大不相同。为了保持整洁并在未来几年更容易维护此应用程序,确实需要在两个不同的文件中定义它们。但是,这会在 device.cpp
内部以及调用 StorageInfo class 的每个其他文件中产生问题。如果我创建两个单独的成员变量,一个用于每种类型的存储,那么我不仅需要插入一百万个不同的 ifelse 语句,而且我有可能 运行 进入构造函数中的初始化问题。相反,我想做的是拥有一个成员变量,它有可能保存任一存储选项 class。像这样:
StorageInfoA.hpp
class StorageInfoA: StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
StorageInfoB.hpp
class StorageInfoB: StorageInfo {
public:
void initializeStorage();
void updateStorageInfo();
int popLocation();
int peakLocation();
uint16_t totalSize();
uint16_t remainingSize();
// More declarations here
private:
//Even more stuff here
}
device.hpp
class device {
public:
// Stuff
private:
// Stuff
StorageInfo storage_info_;
// Even more stuff
}
device.cpp
//Somewhere in the constructor of device.cpp
if(save_to_cache){
storage_info_ = StorageInfoA();
} else {
storage_info_ = StorageInfoB();
}
// Then, these types of calls would return the correct implementation without further ifelse calls
storage_info_.updateStorageInfo();
但是,我知道 cpp 绝对讨厌任何带有动态类型的东西,所以我真的不知道如何实现它。这种事情甚至可能吗?如果没有,有没有人知道可以使用 cpp 的打字规则实现此功能的类似方法?
你的方向是对的,但你必须学会如何使用多态性。在您的示例中,您需要进行以下修复:
在基础class中,将所有函数虚化,并添加一个虚函数 析构函数:
class StorageInfo {
public:
virtual ~StorageInfo(){}
virtual void initializeStorage();
//...
};
继承你的财产public:
class StorageInfoA: public StorageInfo {
不是按值保存 StorageInfo
,而是将其保存在智能指针中:
class device {
private:
std::unique_ptr<StorageInfo> storage_info_;
};
device
构造函数看起来像
//Somewhere in the constructor of device.cpp
if(save_to_cache){
storage_info_ = std::make_unique<StorageInfoA>();
} else {
storage_info_ = std::make_unique<StorageInfoB>();
}
最后,您将像普通指针一样使用它:
storage_info_->updateStorageInfo();