我很難理解爲什麼我的模板層次結構不會傳遞比一層更深的構造函數參數。模板層次結構構造函數參數
到目前爲止,我讀過它可能與名稱空間或模板構造函數未命名有關。我通過範圍指令將構造函數參數傳遞給基類的各種嘗試都失敗了。
// test.cc
#include <string>
// Base class, obviously.
template <typename T>
class Base {
public:
Base(const T& t) : _t(t) {}
virtual ~Base() { }
virtual T getVal() const { return _t; }
private:
T _t;
};
// First derivation. This works, although it is explicit.
class DerivedOne : public virtual Base<std::string>
{
public:
DerivedOne(const std::string& path) : Base<std::string>(path) {}
virtual ~DerivedOne() {}
};
// Second derivation. Constructor fails to compile unless I explicitly
// pass the 'path' argument to Base in the initializer list or create a
// default constructor for Base (which, of course, leaves Base::_t
// uninitialized).
class DerivedTwo : public virtual DerivedOne
{
public:
DerivedTwo(const std::string& path) : DerivedOne(path) {}
// This works
// DerivedTwo(const std::string& path) : DerivedOne(path), Base(path) {}
virtual ~DerivedTwo() {}
};
int main()
{
return 0;
}
編譯器會抱怨:
test.cc: In constructor ‘DerivedTwo::DerivedTwo(const string&)’:
test.cc:31:58: error: no matching function for call to ‘Base<std::__cxx11::basic_string<char> >::Base()’
DerivedTwo(const std::string& path) : DerivedOne(path) {}
^
test.cc:7:5: note: candidate: Base<T>::Base(const T&) [with T = std::__cxx11::basic_string<char>]
Base(const T& t) : _t(t) {}
^
test.cc:7:5: note: candidate expects 1 argument, 0 provided
test.cc:5:7: note: candidate: Base<std::__cxx11::basic_string<char> >::Base(const Base<std::__cxx11::basic_string<char> >&)
class Base {
^
test.cc:5:7: note: candidate expects 1 argument, 0 provided
爲什麼我需要聲明一個默認的構造函數時,它似乎是參數的構造函數應該叫什麼名字?爲什麼我必須顯式地將DerivedTwo的參數傳遞給Base,因爲我已將它傳遞給DerivedOne(誰應該將它傳遞給Base)?
有沒有辦法避免這種重複?這是否意味着當派生類初始化程序列表中的堆上分配了基本模板構造函數參數時,我不能使用初始化程序列表?
這就是虛擬繼承的工作原理。你是否真的想在'class DerivedOne:public virtual Base'和'class DerivedTwo:public virtual DerivedOne'中使用'virtual'?請注意,不需要使用虛擬功能。 –
NathanOliver
在真正的單詞應用程序中,需要虛擬功能。我仍然不明白爲什麼它是必要的,也許我需要重新研究虛擬繼承。 – vincent
只有當您通過多重繼承多次繼承共同祖先時才需要虛擬繼承。 – cababunga