为什么喜欢构图而不是继承呢?每种方法都有哪些权衡取舍?什么时候应该选择继承而不是作文?
如果下面的类不是模板,我可以简单地x在derived课堂上.但是,使用下面的代码,我必须使用this->x.为什么?
template <typename T>
class base {
protected:
int x;
};
template <typename T>
class derived : public base<T> {
public:
int f() { return this->x; }
};
int main() {
derived<int> d;
d.f();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 考虑:
template <typename T>
class Base
{
public:
static const bool ZEROFILL = true;
static const bool NO_ZEROFILL = false;
}
template <typename T>
class Derived : public Base<T>
{
public:
Derived( bool initZero = NO_ZEROFILL ); // NO_ZEROFILL is not visible
~Derived();
}
Run Code Online (Sandbox Code Playgroud)
我无法用GCC g ++ 3.4.4(cygwin)编译它.
在将这些转换为类模板之前,它们是非泛型的,派生类能够看到基类的静态成员.在C++规范的要求中是否会失去可见性,还是需要使用语法更改?
据我了解,每个实例Base<T>都会有它自己的静态成员" ZEROFILL"和" NO_ZEROFILL",这Base<float>::ZEROFILL和Base<double>::ZEROFILL是不同的变量,但我真的不关心; 常量是为了代码的可读性.我想使用静态常量,因为在名称冲突而不是宏或全局方面更安全.
为什么C++编译器不能识别它g()并且b是Superclass此代码中看到的继承成员:
template<typename T> struct Superclass {
protected:
int b;
void g() {}
};
template<typename T> struct Subclass : public Superclass<T> {
void f() {
g(); // compiler error: uncategorized
b = 3; // compiler error: unrecognized
}
};
Run Code Online (Sandbox Code Playgroud)
如果我简化Subclass并Subclass<int>从那时继承它就会编译.它还会编译时完全限定g()为Superclass<T>::g()和Superclass<T>::b.我正在使用LLVM GCC 4.2.
注意:如果我在超类中创建g()并b公开它仍然会失败并出现相同的错误.
以下代码不使用gcc编译,但使用Visual Studio编译:
template <typename T> class A {
public:
T foo;
};
template <typename T> class B: public A <T> {
public:
void bar() { cout << foo << endl; }
};
Run Code Online (Sandbox Code Playgroud)
我收到错误:
test.cpp:在成员函数'void B :: bar()'中:
test.cpp:11:错误:在此范围内未声明'foo'
但它应该是!如果我换bar到
void bar() { cout << this->foo << endl; }
Run Code Online (Sandbox Code Playgroud)
然后它确实编译,但我不认为我必须这样做.GCC在这里遵循C++官方规范中的某些内容,还是仅仅是一个怪癖?
当模板公开继承自另一个模板时,不是应该可访问的基本公共方法吗?
template <int a>
class Test {
public:
Test() {}
int MyMethod1() { return a; }
};
template <int b>
class Another : public Test<b>
{
public:
Another() {}
void MyMethod2() {
MyMethod1();
}
};
int main()
{
Another<5> a;
a.MyMethod1();
a.MyMethod2();
}
Run Code Online (Sandbox Code Playgroud)
好吧,海湾合作委员会对此嗤之以鼻......我必须遗漏一些完全明显的东西(大脑融化).救命?
template<typename T>
class Base
{
protected:
Base() {}
T& get() { return t; }
T t;
};
template<typename T>
class Derived : public Base<T>
{
public:
Base<T>::get; // Line A
Base<T>::t; // Line B
void foo() { t = 4; get(); }
};
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)
如果我注释掉A行和B行,这段代码在Visual Studio 2008下编译得很好.但是当我在GCC 4.1下用A和B行编译时,我得到了以下错误:
在成员函数'void Derived :: foo()'中:
错误:'t'未在此范围内声明
错误:没有依赖于模板参数的'get'参数,因此'get'的声明必须是可得到
为什么一个编译器需要A行和B行而另一个编译器不需要?有没有办法简化这个?换句话说,如果派生类使用基类中的20个东西,我必须为从Base派生的每个类放置20行声明!有没有办法解决这个问题?
我知道默认情况下编译器不能看到"依赖名称".但是我在回答其他SO问题(这里,在这里,最终在C++ faq)时被告知using声明可能有所帮助.
所以我试过了.
模板基类:
// regardless of the fact that members are exposed...
template<typename T>
struct TBase {
typedef T MemberType;
MemberType baseMember;
MemberType baseFunction() { return MemberType(); }
};
Run Code Online (Sandbox Code Playgroud)
和派生类,使用基数的成员:
template<typename T>
struct TDerived : public TBase<T> {
// http://www.parashift.com/c++-faq-lite/nondependent-name-lookup-members.html
// tells us to use a `using` declaration.
using typename TBase<T>::MemberType;
using TBase<T>::baseFunction;
using TBase<T>::baseMember;
void useBaseFunction() {
// this goes allright.
baseFunction();
++baseMember;
// but here, the compiler doesn't want …Run Code Online (Sandbox Code Playgroud) 可能的重复:
GCC问题:使用依赖于模板参数的基类成员
为什么当VS没有时,GCC在模板中需要额外的声明?
为什么派生模板类不能访问基本模板类
iphone编译器继承模板化基类,传递类型未及时扩展(只看)
抱歉这个令人困惑的标题,我能想出最好的.
这里有一些代码来说明我的问题......
基本模板类:
template<class T> class TestBase
{
public:
int someInt;
};
Run Code Online (Sandbox Code Playgroud)
试图用另一个模板类继承TestBase ...
这在编译时得到"someInt未在此范围内声明":
template<class X> class TestSub : public TestBase<X>
{
void testf()
{
someInt = 0; //Error: "someInt was not declared in this scope"
}
};
Run Code Online (Sandbox Code Playgroud)
B)这很好用(不同之处在于我明确指定了TestBase的模板输入)
template<class X> class TestSub : public TestBase<string>
{
void testf()
{
someInt = 0;
}
};
Run Code Online (Sandbox Code Playgroud)
为什么(A)的TestSub没有像(B)中那样正确地继承someInt?
提前致谢.
简介: C++标准区分了依赖于模板参数的符号名称和不符合模板参数的名称,即所谓的两阶段名称查找(参见此处).定义模板时,将尽快解析非依赖名称.另一方面,从属名称仅在模板实例时解析.
例:
template<class T> struct Base {
typedef T type;
static const int n = 3;
virtual int f() = 0;
int f(int x) { return x * 2; }
};
// doesn't compile!
template<class T> struct Derived : Base<T> {
type field; // The compiler doesn't know Base<T>::type yet!
int f() { return n; } // the compiler doesn't know n yet, and f(int) is maksed!
};
Run Code Online (Sandbox Code Playgroud)
目前,我所做的是这样定义Derived:
template<class T> struct Derived : Base<T> …Run Code Online (Sandbox Code Playgroud) 为什么某些编译器会坚持要求模板基类的成员公共成员,而非模板类不需要相同?请查看以下代码清单:
模板类:
#include <iostream>
using namespace std;
template <class T>
class TestImpl {
public: // It wont make a difference even if we use a protected access specifier here
size_t vval_;
TestImpl(size_t val = 0) : vval_(val) { }
};
template <class T>
class Test : public TestImpl<T> {
public:
Test(size_t val) : TestImpl<T>(val) {
cout << "vval_ : " << vval_ << endl; // Error: vval_ was not declared in this scope
//! cout << "vval_ : " << …Run Code Online (Sandbox Code Playgroud) c++ ×10
templates ×9
inheritance ×7
c++-faq ×2
oop ×2
aggregation ×1
base-class ×1
composition ×1
gcc ×1
name-lookup ×1
typedef ×1