In all the languages that I understand this is not possible but someone was telling me it was possible in C++ but I have a hard time believing it. Essentially when you parameterize a class you are creating a unique class in the compilation stage aren't you?
Let me know if I am not being clear with my question.
Here is my attempt at explaning what I am trying to do ( pay attention to class 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 开发者_如何学Cwork
// cout<<l.getMem()<<endl; // why doesn't this work
}
So as you can see (hopefully my syntax makes sense) class L is trying to redefine its parent's float parameter to be a long. It certainly doesn't seem like this is legal but I will differ to the experts.
If you mean to ask whether you can do this in c++ :
template <>
class ParamClass<Type1> : public ParamClass<Type2>
{
};
then yes, it is possible.
It is very often used, for example to define template lists or inherit traits from another type.
What you've asked for can't be done directly -- but you can come pretty close by using a default template parameter:
template <typename T>
class Base { };
template <typename T = int>
class X : Base<T> {};
class Y : Base<float>
class Z : X<long> {};
In this particular case, the default template parameter doesn't add much. You have to supply a template parameter list to instantiate a template, even if defaults are provided for all the parameters. As such, having a default that you override in a derived class is usually only useful for the second and subsequent parameters.
#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 :)
}
the inheritance is private by default in c++, once made public what stephenmm wrote should work unless you meant to ask something else ?
Are you taking about templates?
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>
{};
You should try compiling it:
$ 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 is not a class template, so it makes no sense to try to instantiate it in
class Z: X<long> {};
X has no template parameters to override. Remember that
Base<int>
is not a class template either; it is a class in its own right, but fully instantiated from a template. You could do this:
....
template<typename T>
class X: Base<T>
{};
...
class Z: X<long>
{};
But here there is no confusion about overriding any template parameters.
template<typename T>
class X: Base<int>
{};
...
class Z: X<long>
{};
works too, but here the template parameter in X is unused, and nothing is overridden.
HTH
精彩评论