抽象类和虚拟构造函数的替代方案
abstract class and alternative to virtual constructor
让我有以下代码:
class Block{
private:
data Data;
public:
data getData();
Block(arg3 Arg3, arg4 Arg4);
};
实际上,有几种构建块的方法,但是始终具有相同的成员数据和方法getData((,唯一的区别是如何构建块。换句话说,唯一的区别是构造函数...
,我可以将代码的一部分分解为每个构建过程,而是在抽象类中定义和声明getData的部分,如果C 中有一个虚拟构造函数,我可以为每个派生的派生都有不同的编写。班级对应于不同的建筑过程。
我对这种事情没有很多经验,所以我想知道是否有虚拟构造函数的替代方案?还是可能是进行这种分解的另一种方法?
ps:我知道https://isocpp.org/wiki/faq/virtual-funtions#virtual-ctors,但我想做的事情似乎很复杂,这似乎很普遍...我只想分配几个类之间的共享代码,这与构造函数以外的所有内容相对应。我想强迫与其他建筑过程相对应的新类以实现新的构造函数。
有关我特定情况的更多详细信息:
我有一种使用块的算法,它不取决于它们的构建过程,因此我使用模板参数实现了算法,以表示其建筑过程无关的块。但是我使用一些方法及其构造函数,因此我需要代表块的类具有相同类型的方法,并且使用相同的构造函数将它们用作我算法实现的模板参数。这就是为什么我想到抽象类,强迫新实现的类代表块以具有我实施的算法中所需的方法和构造函数的原因。可能是一个不好的设计模式,这就是为什么我被卡住...
编辑
感谢您到目前为止的回答。我试图有点通用,但我觉得它实际上太模糊了,即使我最后给出了细节。所以这是我想做的:我有一个矩阵类,如下所示
// Matrix.hpp
template<typename GenericBlock> class Matrix{
std::vector<GenericBlock> blocks;
Matrix(arg1 Arg1, arg2 Arg2);
};
template<typename GenericBlock>
Matrix<GenericBlock>::Matrix(arg1 Arg1, arg2 Arg2){
// Do stuff
GenericBlock B(arg3 Arg3, arg4 Arg4);
B.getData();
}
这些块实际上被压缩了,并且有几种压缩它们的方法,并且在类Matrix
中不会更改任何内容。为了避免为每种压缩技术编写矩阵类,我使用了您所看到的模板参数。因此,我只需要为每种压缩技术编写一个类,但是它们必须具有相同的方法和构造函数参数才能与Matrix
兼容。
这就是为什么我想到为每种压缩技术编写课堂的原因。在抽象类中,我将编写Matrix
中所需的所有内容,以便每个派生类都与Matrix
兼容。我现在在示例中的问题是:我可以在抽象类中定义getData
,因为它总是相同的(例如,Data
可以是行的数量(。唯一衍生的类真正需要定义的是构造函数。
一种解决方案是没有抽象类,并且可能使用受保护的构造函数。但这并不迫使新派生的类重新进化构造函数。这就是为什么我被困。但是我认为这个问题足以使其他人感兴趣。那么在这种情况下,是否可以替代虚拟构造函数?(可能是一种工厂模式,但对于这样一个常见的问题来说似乎很复杂(,如果不是这样,是否有更好的方法来实现矩阵类,其块可以以不同的方式构建,即其构造函数可以彼此不同,而具有相同的数据和一些共同的方法?
ps:我对产生低级矩阵的压缩技术感兴趣,这就是为什么数据始终是相同的,但不是建筑过程。
从到目前为止您共享的内容尚不清楚为什么您需要抽象类或虚拟构造函数。每种构建块的工厂功能都会做:
class Block {
Data data;
public:
Block(Data d) : data(std::move(d)) {}
Data getData();
};
Block createABlock() { return Block{Data{1.0, 2.0, 3.0}}; }
Block createBBlock() { return Block{Data{42.0, 3.14, 11.6}}; }
int main() {
auto b1 = createABlock();
auto b2 = createBBlock();
}
现场演示。
也许需要使用抽象工厂扩展这一点,因此您可以通过一般的块工厂通过:
using BlockFactory = std::function<Block()>;
int main() {
BlockFactory f = createABlock;
auto b3 = f();
}
编辑:关于您的编辑,您建议的内容正常。您不需要虚拟构造函数。模板类型GenericBlock
只需要满足模板定义的隐式接口。它不需要源自特定的基类(尽管可以这样做(。它唯一需要的是,它必须具有采用一组特定参数和getData
方法的构造函数。您拥有的是编译时间静态多态性,虚拟功能用于运行时间动态多态性。
继承可以正常工作,但是正如我上面说的那样,我很想使用某种工厂。您可能不需要模板整个Matrix
类,因为仅构造函数需要工厂。如果在编译时已知工厂可以作为模板参数传递:
class Matrix {
std::vector<Block> blocks;
public:
template<typename BlockFactory>
Matrix(BlockFactory f);
};
template<typename BlockFactory>
Matrix::Matrix(BlockFactory f){
// Do stuff...
Block B = f();
auto data = B.getData();
for (auto v : data)
std::cout << v << " ";
std::cout << "n";
}
int main() {
Matrix ma(createABlock);
Matrix mb(createBBlock);
}
live demo。
tl:dr,但是如果data
对于所有Block
S相同,您甚至不需要多个类但是只有多个构造函数。
class Block
{
enum { type1, type2, type3 };
int type;
data Data;
public:
Block(int x)
: type(type1), Data(x) {}
Block(std::string const& str)
: type(type2), Data(str) {}
Block(data const*x)
: type(type3), Data(data) {}
/* ... */
};
template<class T>struct tag_t{constexpr tag_t(){}; usong type=T;};
template<class T>constexpr tag_t<T> tag{};
这使您可以将类型传递为值。
struct BlockA{};
struct BlockB{};
class Block {
enum BlockType { typeA, typeB };;
BlockType type;
data Data;
public:
Block(tag_t<BlockA>, int x)
: type(typeA), Data(x) {}
Block(tag_t<BlockB>, int x)
: type(typeB), Data(2*x+7) {}
/* ... */
};
块都是相同的类型。标签确定了它们的构造方式。
没有一个虚拟构造函数的选择,因为没有虚拟构造函数可以开始。我知道这可能很难接受,但这是事实。
无论如何,您不需要任何虚拟构造函数如果存在的东西。
[..]唯一的区别是如何构建块。换句话说, 唯一的区别是构造函数...
如果唯一的区别是构造函数,则只需使构造函数采用一个参数,该参数告诉需要哪种类型的块。另外,您可以拥有一些以不同方式构建块的功能:
struct Block {
private:
Block(){}
friend Block createWoodenBlock();
friend Block createStoneBlock();
};
Block createWoodenBlock(){ return Block(); }
Block createStoneBlock(){ return Block(); }
int main() {
Block woody = createWoodenBlock();
Block stony = createStoneBlock();
}
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- VS为我提供了对构造函数的另一个解决方案,但我想知道为什么我的工作不起作用
- 抽象类和虚拟构造函数的替代方案
- 正在(在构造函数中)将其包含一个不良设计的指针传递,如果是的,则解决方案是什么