【发布时间】:2018-01-13 12:38:11
【问题描述】:
当你继承T并使用using T::T时,有没有办法在模板中初始化一个const成员?这是一个例子
#include <iostream>
#include <ctime>
#include <string>
#include <memory>
class A {
protected:
int wake_up_time_;
public:
A(int wake_up_time): wake_up_time_(wake_up_time) { }
virtual void hello() const {
std::cout << "I wake up at " << wake_up_time_;
}
};
/* B classes inherit from A and have different members some of which vary in
* size and type */
class B1 : public A {
public:
std::string b;
B1(int a, std::string b): A(a), b(b) { }
};
class B2 : public A {
public:
int c;
double d;
B2(int a, int c, double d): A(a), c(c), d(d) { }
};
template<class T>
class bird : public T {
/* this function is more expensive in my case. */
bool is_early_bird() const { // needs to be const as hello is const
return this->wake_up_time_ < 6;
}
/* would like to have this instead */
// const bool is_early_bird_;
public:
/* which we assign in the constructor */
using T::T;
void hello() const override {
std::cout << (is_early_bird() ? "I am an early bird!" : "Getting up is hard...")
<< std::endl;
}
};
template<class T>
class cat : public T {
/* similar comments as in bird class */
bool is_hunting() const {
return this->wake_up_time_ < 5 || this->wake_up_time_ > 22;
}
public:
using T::T;
void hello() const override {
std::cout << (is_hunting() ? "Time to kill stuff" : "Time to sleep")
<< std::endl;
}
};
int main() {
std::unique_ptr<A> ptr;
{
ptr.reset(new bird<B1>(5, "..."));
std::cout << "B1 has value " << dynamic_cast<B1*>(ptr.get())->b << std::endl;
}
ptr->hello();
{
ptr.reset(new cat<B1>(12, "xyz"));
std::cout << "B1 has value " << dynamic_cast<B1*>(ptr.get())->b << std::endl;
}
ptr->hello();
{
ptr.reset(new cat<B2>(24, 3, 12.5));
B2* l_ptr = dynamic_cast<B2*>(ptr.get());
std::cout << "B2 has value " << l_ptr->c << " and " << l_ptr->d << std::endl;
}
ptr->hello();
{
ptr.reset(new B2(10, 7, 3.33));
B2* l_ptr = dynamic_cast<B2*>(ptr.get());
std::cout << "B2 has value " << l_ptr->c << " and " << l_ptr->d << std::endl;
}
ptr->hello();
return 0;
}
输出是
B1 has value ...
I am an early bird!
B1 has value xyz
Time to sleep
B2 has value 3 and 12.5
Time to kill stuff
B2 has value 7 and 3.33
I wake up at 10
我想摆脱的是cat::is_hunting 和bird::is_early_bird 中的(在这种情况下很简单)计算,而是使用 const 成员。我还有很多函数,它接受一个引用或指向B1 或B2 类的指针作为参数,因此拥有public cat : public A 和public bird : public A 类并以2x2 继承的B 类结束似乎不是一个选项。
【问题讨论】:
-
是什么阻止了你?尝试时遇到什么错误?没有更简单的代码可以重现吗?
-
@W.F. 没有更简单的代码可以重现吗?我想强调我有多个类,如
B1和B2以及多个类,如cat和bird以避免我使用的 cmets例如,可以让cat继承自A。此外,我还想强调B1和B2在构造函数参数的数量及其类型方面有所不同。 -
@W.F. 是什么阻止了你?尝试时遇到什么错误? 如何使用
using T::T和const bool is_early_bird_成员初始化类bird而没有bird::is_early_bird函数? -
aaam...[this]?
-
我敢打赌它是 c++11。很高兴它有帮助。
标签: c++ templates constructor initialization