0

我在 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 示例中看到的那样,各种构造函数之间没有重复的代码。问题:

  1. 有没有办法在 C++ 中实现同样的效果?
  2. 如果有怎么办?你能提供一个样品吗?
  3. 如果不是,您推荐什么解决方案来解决这个问题?
4

3 回答 3

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 );
}

正如@chris 所评论的,在 C++11中,允许构造函数调用其他构造函数。您可以通过以下方式更改构造函数:

//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];
}
于 2013-03-17T19:12:33.153 回答
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 方法包括构造函数转发。


顺便说一句,请注意您的原始代码违反了“三原则”,即它需要禁止或明确支持复制,但未能做到这一点。上面提出的简化不存在这个问题。你能看出为什么吗?

于 2013-03-17T19:20:18.123 回答
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>forbuffer而不是自己管理内存。

于 2013-03-17T19:16:59.613 回答