0

我想创建两种类。这些类将具有类似的函数“set”,但 set 函数将在 B 类中获得“int”,在 C 类中获得双倍。(A 是抽象类,但它不需要)。我需要做什么?

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

4 回答 4

2

创建一个模板类并实例化您当时需要的任何一个,或者从模板类中 typedef 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;
于 2013-02-24T19:46:30.443 回答
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 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 中不需要虚拟析构函数,但这不太安全。

这些只是一些变体,可能还有更多,哪一个最适合您,您只能根据您的程序要求来决定。

于 2013-02-24T19:57:04.197 回答
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
}

注意类末尾的分号Aint main代替void main.

这样的细节很重要。

否则,您可以派出想帮助您的人,进行漫长的追逐。而你不想那样,是吗?因此,请确保您发布的代码已被编译器接受,除非您想要显示的麻烦部分无法编译。

于 2013-02-24T19:57:14.630 回答
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;
}

函数看起来相同,但实际上调用不同的运算符>>。

于 2013-02-24T19:44:29.617 回答