2010-01-05 42 views
0

在我理解的所有语言中,这是不可能的,但有人告诉我可以在C++中使用,但我很难相信它。基本上,当你参与一个类,你正在编译阶段创建一个独特的类,不是吗?在C++中,您可以在子类中使用不同的参数值来扩展参数化的基类吗?

让我知道如果我不清楚我的问题。

这是我在地名释义什么,我试图做(要注意L类)的尝试:

//; g++ ModifingBaseClassParameter.cpp -o ModifingBaseClassParameter;ModifingBaseClassParameter 

#include <iostream> 

using namespace std; 

template<typename T> 
class Base 
{ 
    public: 
     Base() {} 
     Base(T& t) : m_t(t) {} 
     T& getMem() {return m_t;} 
    private: 
     T m_t; 
}; 

template<typename T> 
class F: Base<T> 
{}; 

template<typename T> 
class L: F<long> 
{}; 

int main() 
{ 
    Base<int> i; 
    F<float> f; 
    L<long> l; 

    cout<<i.getMem()<<endl; 
//  cout<<f.getMem()<<endl; // why doesn't this work 
//  cout<<l.getMem()<<endl; // why doesn't this work 
} 

因此,大家可以看到(希望我的语法是有道理的),L类是试图重新定义其父母的浮动参数很长。这似乎并不合法,但我会对专家有所不同。

+1

发布一些代码,说明你在问什么。 – 2010-01-05 21:43:49

+0

我认为你需要澄清你的问题。 – 2010-01-05 21:45:50

+0

您问关于foo类然后制作一个类吧:public foo <4>? – wheaties 2010-01-05 21:47:33

回答

2

如果你的意思是问你是否能在C++中做到这一点:

template <> 
class ParamClass<Type1> : public ParamClass<Type2> 
{ 
}; 

然后是的,这是可能的。

它经常用于例如定义模板列表或继承其他类型的特征。

0

您是否正在关注模板?

template<typename T> 
class Base 
{ 
    public: 
     Base() {} 
     Base(T& t) : m_t(t) {} 
     T& getMem() {return m_t;} 
    private: 
     T m_t; 
}; 

class X: Base<int> 
{}; 

class Y: Base<float> 
{}; 
+0

为何不在启动(不可编译)代码之前验证问题? – 2010-01-05 21:48:45

+0

因为我沉迷于写作。 – 2010-01-05 21:51:46

+1

马丁我不想在你这里或其他任何人对你很恐怖,但是当任何人提出一个模糊的问题时,最好的办法就是等待他们扩大这个问题。如果我们都等待,想想这会是一个更好的网站!一个大而快乐的气球! – 2010-01-05 21:56:48

0

你应该尝试编译它:

$ g++ so-test1.c++ -o so-test1.c++ && ./so-test 
so-test1.c++:21: error: expected template-name before ‘<’ token 
so-test1.c++:21: error: expected `{' before ‘<’ token 
so-test1.c++:21: error: expected unqualified-id before ‘<’ token 
so-test1.c++: In function ‘int main(int, const char**)’: 
so-test1.c++:27: error: aggregate ‘Z z’ has incomplete type and cannot be defined 

X不是一个类模板,所以它是没有意义的尝试实例它

class Z: X<long> {}; 

X没有模板参数覆盖。请记住,

Base<int> 

也不是类模板;它本身是一个类,但是完全从模板实例化了。你可以这样做:

.... 
template<typename T> 
class X: Base<T> 
{}; 
... 
class Z: X<long> 
{}; 

但是这里没有关于覆盖任何模板参数的混淆。

template<typename T> 
class X: Base<int> 
{}; 
... 
class Z: X<long> 
{}; 

也可以工作,但这里X中的模板参数未被使用,也没有被覆盖。

HTH

2

你问什么不能直接做 - 但你可以来通过使用默认模板参数非常接近:

template <typename T> 
class Base { }; 

template <typename T = int> 
class X : Base<T> {}; 

class Y : Base<float> 

class Z : X<long> {}; 

在这种特殊情况下,默认模板参数不会增加太多。即使为所有参数提供了默认值,您也必须提供模板参数列表来实例化模板。因此,在派生类中重写默认值通常仅对第二个和后续参数有用。

1
#include <iostream> 
#include <typeinfo> 

using namespace std; 

template<typename T> 
class Base 
{ 
    public: 
     Base() {} 
     Base(T& t) : m_t(t) {} 
     T& getMem() {return m_t;} 
    private: 
     T m_t; 
}; 

template<typename T> 
class F: public Base<T> 
{}; 

template<typename T> 
class L: public F<long> 
{}; 

int main() 
{ 
    Base<int> iNTEGER; 
    F<float> fLOAT; 
    L<long> lONG; 

    int x; 
    cout << typeid(iNTEGER.getMem()).name() << endl; 
    cout << typeid(fLOAT.getMem()).name() <<endl; // this works now :) 
    cout << typeid(lONG.getMem()).name() <<endl; // this works now :) 
} 

继承是默认私有的C++中,一旦公开什么stephenmm写道应该工作,除非你打算要问别的东西?