清除c++构造函数中重复的代码
clean repeated code in C++ constructors
我有一个c++头文件,为用户提供了几个构造函数(这是一个要求):
#ifndef IMANDEL_H_
#define IMANDEL_H_
class IMandel{
public:
IMandel();
IMandel(int aWidth, int aLength);
IMandel(int threads, int aWidth, int aLength);
//other stuff!
private:
int max_iterations, thread_count, height, width;
int* buffer;
};
#endif
因此,在相应的cpp文件中,我分别实现了这些构造函数:
//default constructor
IMandel::IMandel(){
height = 10000;
width = 10000;
//this code segements gets repeated in every constructor! Messy!
max_iterations = 255;
thread_count = 1;
buffer = new int[width*height];
}
IMandel::IMandel(int aWidth, int aLength){
width = aWidth;
height = aLength;
//this code segements gets repeated in every constructor! Messy!
max_iterations = 255;
thread_count = 1;
buffer = new int[width*height];
}
IMandel::IMandel(int threads, int aWidth, int aLength){
thread_count = threads;
width = aWidth;
height = aLength;
//this code segements gets repeated in every constructor! Messy!
max_iterations = 255;
buffer = new int[width*height];
}
正如您所看到的,我的构造函数是不健康的,它们到处都是重复的代码块,这太可怕了!
在java中,我通过使用构造函数相互调用找到了这个问题的解决方案。基本上,我像下面这样重用构造函数(Java示例):
public myClass(){
this(1, 10000, 10000);
}
public myClass(int aWidth, int aLength){
this(1, aWidth, aLentgh);
}
public myClass(int threads, int aWidth, int aLength){
thread_count = threads;
width = aWidth;
height = aLength;
max_iterations = 255;
buffer = new int[width*height];
}
正如您在这个Java示例中看到的,不同的构造函数之间没有重复的代码。问题:
- 有没有办法在c++中实现同样的效果?
- 如果是,如何?你能提供样品吗?
- 如果没有,您建议如何解决这个问题?
实际的解决方案各不相同,这取决于您使用的是哪个版本的c++。
在c++ 03中,一种常见的(但不完美-参见底部有用的注释)方法是创建一个所有构造函数调用的init()
函数。所有三个构造函数都可以是一行,这样调用函数:
void IMandel::init(int threads, int aWidth, int aLength){
thread_count = threads;
width = aWidth;
height = aLength;
//this code segements gets repeated in every constructor! Messy!
max_iterations = 255;
buffer = new int[width*height];
}
//default constructor
IMandel::IMandel(){
init( 1, 10000, 10000 );
}
IMandel::IMandel(int aWidth, int aLength){
init( 1, aWidth, aLength );
}
IMandel::IMandel(int threads, int aWidth, int aLength){
init( threads, aWidth, aLength );
}
在c++ 11中,允许构造函数调用其他构造函数,就像@chris注释的那样。你可以这样修改你的构造函数:
//default constructor
IMandel::IMandel()
: IMandel( 1, 10000, 10000 )
{
}
IMandel::IMandel(int aWidth, int aLength)
: IMandel( 1, aWidth, aLength )
{
}
IMandel::IMandel(int threads, int aWidth, int aLength){
thread_count = threads;
width = aWidth;
height = aLength;
//this code segements gets repeated in every constructor! Messy!
max_iterations = 255;
buffer = new int[width*height];
}
采用哪种解决方案取决于具体情况。
这是你当前的类定义:
class IMandel
{
public:
IMandel();
IMandel(int aWidth, int aLength);
IMandel(int threads, int aWidth, int aLength);
//other stuff!
private:
int max_iterations, thread_count, height, width;
int* buffer;
};
我是这样定义它的:
class IMandel
{
public:
IMandel( int aWidth = 10000, int aLength = 10000, int threads = 1 );
//other stuff!
private:
int max_iterations, thread_count, height, width;
std::vector<int> buffer;
};
注意,除了参数顺序之外,这仍然给了你原来的明显的构造函数。
没有必要把事情弄得过于复杂,也就是说,KEEP IT SIMPLE。然而,c++ 03的其他方法包括一个通用的init
函数(如果适用的话,不在这里)和一个通用的人工基类。其他c++ 11方法包括构造函数转发。
顺便说一下,请注意你的原始代码违反了"三规则",即它需要禁止或显式支持复制,但没有做到这一点。上面给出的简化不会受到这个问题的影响。你知道为什么吗?
如果你的编译器支持c++ 11的委托构造函数,可以减少构造函数中重复的代码。在你的情况下,似乎你只需要为你的构造函数参数提供默认值。
#ifndef IMANDEL_H_
#define IMANDEL_H_
class IMandel{
public:
IMandel(int aWidth = 10000, int aLength = 10000, int threads = 1);
private:
int max_iterations, thread_count, height, width;
int* buffer;
};
#endif
IMandel::IMandel(int aWidth, int aLength, int threads)
: max_iterations(255)
, thread_count(threads)
, height(aLength)
, width(aWidth)
, buffer(new int[width*height])
{
}
上面的构造函数完成了您所展示的3所做的一切。另外,考虑为buffer
使用vector<int>
,而不是自己管理内存。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值