我在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示例中看到的那样,各种构造函数之间没有重复的代码。 问题:
答案 0 :(得分:7)
实际解决方案因您使用的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];
}
答案 1 :(得分:3)
采用什么解决方案取决于具体案例。
这是您当前的课程定义:
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;
};
请注意,除了参数顺序之外,这仍然为您提供了原来拥有的明显的构造函数。
没有必要让事情变得更加复杂,即保持简单。其他C ++ 03意味着包括一个共同的init
函数(当它适用时,不在这里),以及一个常见的人工基类。其他C ++ 11意味着包括构造函数转发。
顺便说一句,请注意您的原始代码违反了“三规则”,即它需要禁止或明确支持复制,但未能这样做。上面提到的简化不会遇到这个问题。你能明白为什么吗?
答案 2 :(得分:2)
如果您的编译器支持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所做的一切。另外,请考虑使用vector<int>
buffer
而不是自己管理内存。