从构造函数初始化列表调用重载构造函数
Calling overloaded constructor from constructor initialisation list
在下面的代码中,我的意图是根据传递给类material
的对象的参数调用kap
(类opacity
)的两个重载构造函数之一:
class opacity{
private:
int mode;
double kap_const;
double kappa_array[10][10];
public:
opacity(double constkap); // picking the constructor sets the mode
opacity(char* Datafile);
double value(double T, double P); // will return a constant or interpolate
};
opacity::opacity(double constkap):mode(1){
kap_const = constkap;
}
opacity::opacity(char* Datafile):mode(2){
// read file into kappa_array...
}
class Matter {
public:
Matter(int i, double k, char* filename); // many more values are actually passed
opacity kap;
int x; // dummy thing
// more variables, call some functions
};
Matter::Matter(int i, double k, char * filename)
:x(k>0? this->kap(x): this->kap(filename) ) {
// ... rest of initialisation
}
但是这行不通:
test.cpp: In constructor 'Matter::Matter(int, double, char*)':
test.cpp:32:21: error: no match for call to '(opacity) (void*&)'
test.cpp:32:42: error: no match for call to '(opacity) (char*&)'
test.cpp:32:44: error: no matching function for call to 'opacity::opacity()'
test.cpp:32:44: note: candidates are:
test.cpp:20:1: note: opacity::opacity(char*)
test.cpp:20:1: note: candidate expects 1 argument, 0 provided
test.cpp:16:1: note: opacity::opacity(double)
test.cpp:16:1: note: candidate expects 1 argument, 0 provided
test.cpp:4:7: note: opacity::opacity(const opacity&)
test.cpp:4:7: note: candidate expects 1 argument, 0 provided
我试过的第一件事,
Matter::Matter(int i, double k, char * filename)
:kap(k>0? k: filename) { // use k<0 as a flag to read from filename
// ... rest of initialisation
}
也失败了,因为由于编译时的原因,"三元操作符的结果总是必须是相同的类型",正如在一个类似的问题中指出的那样(尽管那里似乎没有解释)。
现在,不雅的解决方案是还超载Matter
构造函数基于kap
构造函数应该接受的争论,但这是(1)非常不雅的,尤其是Matter
构造函数变量和执行许多操作(所以很多代码是重复的只是改变kap
构造函数初始化列表的一部分),和(2)这可能失控如果有另一个类用于Matter
也有不同的构造函数:对于具有N c'变量的M类,最终得到N^ M组合…
有人有建议或解决方法吗?提前感谢!
如果不透明度有复制构造函数,您可以在初始化列表中完成此操作,避免使用默认构造函数,但以复制为代价:
Matter::Matter(int i, double k, char * filename)
:kap( ( 0 < k ) ? opacity(k) : opacity( filename ) ) { ... }
您将不得不为opacity
添加默认构造函数(可能将模式设置为0
以指示无效模式),并在构造函数体中为kap
赋值。
Matter::Matter(int i, double k, char * filename) {
if(k > 0)
kap = opacity(k);
else
kap = opacity(filename);
}
k
为运行时值。不可能使类型和重载结果依赖于运行时值。
为了避免复制开销,假设您有一个c++ 0x编译器,您可以给opacity一个move构造函数,并根据您的逻辑提供一个opacity
的实例,并使用返回的临时opacity
初始化您的kap
成员。
你可能想让kappa_array
成为像auto_ptr<double>
一样的指针。虽然如果这个数据是在一个闭环中使用的,但与指针的位置和解引用的成本相比,可移动性所节省的成本可能是不确定的。
opacity& get_opacity(double k, char * filename) {
if(k > 0)
return opacity(k);
else
return opacity(filename);
}
Matter::Mater(int i, double k, char * filename)
: kap(get_opacity(k, filename) {
//...
}
opacity::opacity(opacity&& other)
: mode(other.mode),
kap_const(other.kap_const),
kappa_array(std::move(kappa_array)) { }
请不要测试我这个,我是很新的移动语义和右值引用我自己…
不能使用三元操作符来选择函数覆盖,因为该操作符的结果只有一个类型。在不同分支具有不同类型的情况下,它们将被强制转换为结果类型,否则将出现编译时错误。见http://en.wikipedia.org/wiki/%3F: # Result_type
不可能有其他的方式。类型需要在编译时被编译器知道,但是操作的结果直到运行时才知道。
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- 两种类型的构造函数重载
- C++ 构造函数重载 - 为什么说我需要括号?
- C++具有多重继承的构造函数重载解析
- C++,处理多个构造函数重载和冗余代码
- c++ 构造函数重载歧义与initializer_list
- 父类有 26 个构造函数重载.如何在不复制+粘贴 26 个重载的情况下将一个小任务附加到所有构造器?
- 用户定义的构造函数重载与参数超类的重载不匹配
- 模板专用类之间的构造函数重载
- 指向构造函数重载的指针?
- C++简化了构造函数重载
- 类构造函数重载不起作用
- C++类模板构造函数 -- 重载引用 (U&) 与数组 (U*) 失败
- 为什么存在 C++11 std::initializer_list 构造函数重载规则
- 构造函数重载和默认参数
- 模板类构造函数重载解析
- 单例中的构造函数重载不起作用
- 构造函数重载选择了强制转换运算符而不是结构类型
- c++ 11构造函数重载解析和initialiser_lists: clang++和c++不一致.< / h1 &
- C++构造函数重载的经验法则