C++ c+中的类+;与虚函数

C++ c+中的类+;与虚函数,c++,class,virtual,C++,Class,Virtual,我想创建两种类型的类。 这些类将有类似的函数“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{

我想创建两种类型的类。 这些类将有类似的函数“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
}

诀窍是找到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;
}

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

诀窍是找到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;
}

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

创建一个模板类并实例化您当时需要的模板类,或者从模板类中键入def 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;
模板A类
{
public:A():mValue(){}
无效集(T值){mValue=value;}
私有:T值;
};
类型定义AB;
类型定义AC;

创建单个模板类并实例化您当时需要的模板,或从模板类键入def 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;
模板A类
{
public:A():mValue(){}
无效集(T值){mValue=value;}
私有:T值;
};
类型定义AB;
类型定义AC;

解决这个问题有很多变体,但首先,虚拟函数必须具有相同的签名(可能会有例外,但这与您的情况无关)。所以,解决方法就是用一个或多个参数来解决所有的问题。有几种变体:

将所有变量传递给函数,并仅使用特定变量:

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; }
};
struct Arg{
虚拟~Arg();
};
结构IntArg:Arg{
int m_值;
};
结构DoubleArg:Arg{
双m_值;
};
甲级{
虚空集(常量参数&a)=0;
};
B类{
int-y;
公众:
虚空集(const Arg&a){y=dynamic_cast(a).m_value;}
};
C类{
双y;
公众:
虚空集(const Arg&a){y=dynamic_cast(a).m_value;}
};
您可以使用static_cast,这样您就不需要Arg中的虚拟析构函数,但这样做不太安全


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

有很多变体可以解决这个问题,但首先,虚拟函数必须具有相同的签名(可能有例外,但这与您的情况无关)。所以,解决方法就是用一个或多个参数来解决所有的问题。有几种变体:

将所有变量传递给函数,并仅使用特定变量:

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; }
};
struct Arg{
虚拟~Arg();
};
结构IntArg:Arg{
int m_值;
};
结构DoubleArg:Arg{
双m_值;
};
甲级{
虚空集(常量参数&a)=0;
};
B类{
int-y;
公众:
虚空集(const Arg&a){y=dynamic_cast(a).m_value;}
};
C类{
双y;
公众:
虚空集(const Arg&a){y=dynamic_cast(a).m_value;}
};
您可以使用static_cast,这样您就不需要Arg中的虚拟析构函数,但这样做不太安全


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

放弃继承和虚拟的东西。您无法通过虚拟函数轻松访问静态未知类型的结果。因此:

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

这些细节很重要


否则,你可以派想要帮助你的人去做漫长的“雁行追逐”。你不想那样,是吗?因此,请确保您发布的代码已被编译器接受,除非您希望显示的麻烦部分未编译。

放弃继承和虚拟内容。您无法通过虚拟函数轻松访问静态未知类型的结果。因此:

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

这些细节很重要


否则,你可以派想要帮助你的人去做漫长的“雁行追逐”。你不想那样,是吗?因此,请确保您发布的代码已被编译器接受,但您希望显示的麻烦部分可能不被编译。

使用继承创建两个单独的类。这两个计算器是B和C。使用模板比使用模板更合适inheritence@YkI你的问题中没有任何东西表明你需要继承。避免使用getter和setter。他们把你和一个代表紧密地结合在一起。而是公开可应用于对象的操作。创建两个不带继承的独立类?带继承。这两个计算器是B和C。使用模板比使用模板更合适inheritence@YkI你的问题中没有任何东西表明你需要继承。避免使用getter和setter。他们把你和一个代表紧密地结合在一起。而是公开可应用于对象的操作。B和C具有相同的“int x”和不同的变量“float C”和“int a”。我还希望B和C将共享相同名称的函数“set”