我想创建两种类。 类将具有类似的功能“set”,但set funct将在类B中获得“int”并在类C中获得double。(A是抽象calss但不需要)。 我需要做什么?
class A{
int x;
public:
A (int t=1): x(t){}
virtual void set ()=0;
}
class B: public A{
int y;
public:
virtual void set (int y);
};
class C: public A{
double y;
public:
virtual void set (double y);
};
void main ()
{
B b; //error
C c; //error
}
答案 0 :(得分:2)
创建单个模板类并实例化当时所需的模板类,或者从模板类中键入B和C:
template< typename T > class A
{
public: A() : mValue() {}
void Set( T value ) { mValue = value; }
private: T mValue;
};
typedef A< int > B;
typedef A< double > C;
答案 1 :(得分:1)
有很多变种可以解决这个问题,但首先,虚函数必须具有相同的签名(可能存在异常,但这与您的情况无关)。因此,解决方案是拥有可以解决所有情况的参数。有变种:
将所有变体传递给函数,并仅使用特定的变体:
class A {
public:
virtual void set( int, double ) = 0;
};
class B {
int y;
public:
virtual void set( int val, double ) { y = val; }
};
class C {
double y;
public:
virtual void set( int , double val ) { y = val; }
};
这不是很好的解决方案,也不能很好地扩展,所以我们可以使用union:
Union Arg {
int i;
double d;
};
class A {
public:
virtual void set( Arg a ) = 0;
};
// derived classes are trivial, so omitted
Union不是类型安全的,所以我们可以使用boost :: variant
另一个有参数层次结构的解决方案:
struct Arg {
virtual ~Arg();
};
struct IntArg : Arg {
int m_value;
};
struct DoubleArg : Arg {
double m_value;
};
class A {
virtual void set( const Arg &a ) = 0;
};
class B {
int y;
public:
virtual void set( const Arg &a ) { y = dynamic_cast<const IntArg &>( a ).m_value; }
};
class C {
double y;
public:
virtual void set( const Arg &a ) { y = dynamic_cast<const DoubleArg &>( a ).m_value; }
};
您可以使用static_cast,然后在Arg中不需要虚拟析构函数,但这样做不太安全。
这些只是一些变体,可能会有更多,哪一个最适合你,你只能根据你的计划要求来决定。
答案 2 :(得分:1)
抛弃继承和虚拟事物。您无法通过虚拟功能轻松访问静态未知类型的结果。所以:
class A
{
private:
int x_;
public:
A( int const t = 1 ): x_( t ) {}
};
class B
: public A
{
private:
int y_;
public:
void set( int const y );
};
class C
: public A
{
private:
double y_;
public:
void set( double const y );
};
int main ()
{
B b; // OK
C c; // OK
}
请注意课程A
末尾的分号和int main
代替void main
的分号。
这些细节很重要。
否则你可以派遣想要帮助你的人进行漫长的追逐。而且你不想那样,是吗?因此,请确保您发布的代码已被编译器接受,除非您想要显示的麻烦部分不能编译。
答案 3 :(得分:0)
诀窍是找到B和C的公共部分,并将它们放到基类中。不同的东西应该转到派生类的构造函数参数:
class A {
virtual std::string get() const=0;
virtual void set(std::string s)=0;
};
class B : public A { B(int a) : a(a) { } int a; };
class C : public A { C(float b) : b(b) { } float b; }
要实现这些功能,您需要以下内容:
void B::set(std::string s) {
stringstream ss(s);
ss >> a;
}
void C::set(std::string s) {
stringstream ss(s);
ss >> b;
}
函数看起来相同,但实际上调用的是不同的运算符&gt;&gt;。