重构从std::容器继承的类
Refactoring a class which inherited from a std::container
我有一个中等大小的代码块,包含5个类,它们都是从标准容器继承的。例如:
class Step : public std::vector<unsigned int>
{
public:
friend std::ostream& operator<<(std::ostream& outStream, const Step& step);
Step& operator =(const Step& rhv);
static Step fromString(const std::string &input);
std::string name;
};
我知道从标准容器继承是个坏主意,所以我将通过添加父数据类型的子对象来删除所有继承:
class Step
{
public:
friend std::ostream& operator<<(std::ostream& outStream, const Step& step);
Step& operator =(const Step& rhv);
static Step fromString(const std::string &input);
std::string name;
// std::vector interface:
inline std::vector<unsigned int>::const_iterator begin() const {return data.begin();}
inline std::vector<unsigned int>::const_iterator end() const {return data.end();}
inline size_t size() const {return data.size();}
typedef std::vector<unsigned int>::const_iterator const_iterator;
private:
std::vector<unsigned int> data;
};
我这样做是因为代码在其他程序中被广泛使用,并且更改结构的成本非常高。
问题是:你建议如何通过小的修改来修改代码?(尽可能少)
澄清:我有一些从stl容器继承的类。有很多代码在使用它们。我的问题是,如何在不更改使用这些类的代码的情况下删除这种邪恶的继承?
我知道从标准容器继承是个坏主意
这在很多情况下都是有道理的。如果你认为总是是个坏主意,那么你错了。如果从标准容器继承使代码变得简短且易于阅读,那么从STL容器继承是个好主意。在MY看来,您的第一个类(继承std::vector)比第二个好。
问题是:你建议如何通过小的修改来修改代码?
如果你只想浪费时间…
首先,你可以删除"公共朋友"功能,这没有任何意义。
之后声明几个typedef。
typedef std::string Name;
class Step{
protected:
typedef std::vector<int> Data;
Data data;
public:
typedef Data::const_iterator ConstIterator;
Step& operator=(const Step& other);
static Step fromString(const std::string &input);
Name name;
ConstIterator begin() const;
ConstIterator end() const;
size_t size() const;
};
并在所有与Step交互的代码中使用这些typedeffed类型。这样,您以后就可以更改内部类型(例如,用std::deque替换std::vector,或者实现自定义迭代器类),而无需修改整个项目。
一个潜在的解决方案:使继承私有(或受保护,如果有意义的话),并将using
作为相关成员:
class Step : private std::vector<int>
{
typedef std::vector<int> base_;
public:
using base_::operator[];
using base_::size;
...
};
如果继承确实简化了代码,那么您可能会喜欢这个解决方案。从容器继承的真正问题是,一旦向Step
类添加成员,向vector
的转换可能会给您带来麻烦:析构函数会更改,而且您知道,它一开始就不是虚拟的。私有继承解决了这个问题。
最好的解决方案是首先将您的功能重构为免费功能:
namespace Step2 {
std::vector<unsigned int> fromString(const std::string &input);
}
然后为旧的API提供一个独立的头:
DEPRECATED class Step : public std::vector<unsigned int>
{
public:
inline static Step fromString(std::string const& input);
{
return Step(Step2::fromString(input));
}
};
typedef std::vector<unsigned int> data_t;
data_t data;
引入typedef简化了方法的所有签名,并降低了向量类型更改的风险
- 可以从std::string继承以提供类型一致性吗
- "std::shared_from_this"不能由其派生类继承吗?
- 从 std::数组私下继承时无法从 std::initializer_list 构造
- C++ std::vector 中的虚拟析构函数继承
- 当键是虚拟继承中涉及的基类指针时,对 std::unordered_map 项的访问崩溃
- 在继承自 std::variant 的类上使用 std::visit——libstdc++ 与 libc++
- std::exception :使用虚函数和继承与变量
- 如何创建一个继承自 std::vector 的类
- 是否可以通过使用 std::variant 来避免继承
- std::bad_weak_ptr 从基类继承 std::shared_from_this 时
- C++通过继承 std::exception 来创建新的异常
- 为自定义类继承std::vector::迭代器
- 错误:当我继承 std::vector 时,在“开始”之前预期“)”
- 如何在 C++11 的用户自定义类模板中继承 std::vector 模板
- 在继承std::vector的类中使用操作符[]
- c++ -从其他对象继承std::元组,并为其添加虚函数
- 尝试继承std::runtime_error时出现编译错误
- 继承 std::容器,包括其提升序列化
- 继承std::basic_streambuf的问题
- 继承std::string类时跳过添加构造函数