接下来的代码展示了类参数包装器,它允许通过 getter 和 setter 访问底层类。简化版:
template<typename T>
class Parameter
{
public:
typedef T value_type;
typedef Parameter<T> Type;
protected:
T value_;
public:
Parameter() { this->value_ = this->default_value(); }
Parameter(T&& val) { this->set(std::forward<T>(val)); }
Parameter(const T& val) { this->set(std::forward<T>(val)); }
virtual ~Parameter() {};
// Get
T& get() { return this->value_/*this->getter()*/; }
operator T&() { return this->get(); }
// Set
Type& set(T&& val)
{
std::cout << "T&& setter called with " << val << std::endl;
value_ = this->setter(std::forward<T>(val));
return *this;
}
Type& set(const T& val)
{
std::cout << "constT& setter called with " << val << std::endl;
value_ = this->setter(std::forward<const T>(val));
return *this;
}
Type& operator=(T const& val) { return this->set(val); }
Type& operator=(T&& val) { return this->set(val); }
virtual T setter(T const& val) { return val; }
virtual const T& default_value()
{
static const T default_value_{};
return default_value_;
};
};
使用:
int main()
{
struct IncrementorPar : Parameter<int>
{
using Parameter::Parameter; //todo HIDE
using Parameter::operator=; //todo HIDE
virtual int setter(int const& val) { return val + 1; }
virtual const int& default_value(){ return -1; };
} in1(1), in2 = 2, int0;
//assert(int0==int0.default_value()); //FAIL
//assert(int0==-1); //FAIL
//assert(in1 == 2); //FAIL
//assert(in2 == 3); //FAIL
auto *pi1 = new IncrementorPar(2);
//assert(*pi1==3); //FAIL
pi1->set(2);
assert(*pi1==3);
*pi1 = 33;}
}
如何从祖先的构造函数调用后代的方法 setter()
和 default_value()
?
如何隐藏 using
?
最佳答案
这不是一个优雅的解决方案,但是......
您可以使用 init()
函数推迟 value_
的初始化。
有点像
template<typename T>
class Parameter
{
private:
bool toInit { true };
bool initWithVal;
T valInit;
void init ()
{
if ( initWithVal )
this->set(valInit);
else
value_ = this->default_value();
toInit = false;
}
public:
typedef T value_type;
typedef Parameter<T> Type;
protected:
T value_;
public:
Parameter() : initWithVal{false} { }
Parameter(T&& val) : initWithVal{true}, valInit{std::move(val)} { }
Parameter(const T& val) { this->set(std::forward<T>(val)); }
virtual ~Parameter() {};
// Get
T& get() { if ( toInit ) init(); return this->value_/*this->getter()*/; }
operator T&() { return this->get(); }
// Set
Type& set(T&& val)
{
toInit = false;
std::cout << "T&& setter called with " << val << std::endl;
value_ = this->setter(std::forward<T>(val));
return *this;
}
Type& set(const T& val)
{
toInit = false;
std::cout << "constT& setter called with " << val << std::endl;
value_ = this->setter(std::forward<const T>(val));
return *this;
}
Type& operator=(T const& val) { return this->set(val); }
Type& operator=(T&& val) { return this->set(val); }
virtual T setter(T const& val) { return val; }
virtual const T& default_value()
{
std::cout << "base default value\n";
static const T default_value_{};
return default_value_;
};
};
关于c++ - 从祖先的方法和构造函数调用后代的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39710542/