c ++和虚函数中的类

时间:2013-02-24 19:34:47

标签: c++ class virtual

我想创建两种类。 类将具有类似的功能“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
}

4 个答案:

答案 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;。