переопределение и перегрузка методов - PullRequest
1 голос
/ 18 декабря 2009

Могу ли я перегрузить или переопределить методы, просто используя другое возвращаемое значение? В этом случае виртуальная материя?

например:

class A{

  virtual int Foo(); // is this scenario possible with/without the keyword virtual
}

class B : public A {
   virtual double Foo();
}

A* Base = new B();
int i = Base->Foo(); // will this just convert double to int ?

и относительно перегрузки:

class A{

  virtual int Foo(); 
  virtual float Foo(); // is this possible ?

  int Goo();
  float Goo(); // or maybe this ?
}

Class B{
    double Foo();
}

спасибо

Ответы [ 8 ]

8 голосов
/ 18 декабря 2009

Тип возвращаемого значения функции не является частью ее подписи, поэтому его нельзя перегрузить.

4 голосов
/ 18 декабря 2009

Нет, вы не можете этого сделать.

То, что вы можете сделать в переопределенном методе, это вернуть указатель / ссылку на тип, который является потомком типа, возвращаемого методом родителя.

Пример:

struct VA {}
struct VB : struct VA {}

class A
{
public:
    virtual VA * get();
}

class B
{
public:
    virtual VB * get();
}
4 голосов
/ 18 декабря 2009

Возвращаемое значение не является частью сигнатуры функции. Как теперь компилятору выбрать версию для выбора?

Если вы удалите virtual из Foo в вашем первом примере, это сработает и вызовет Base::Foo.

1 голос
/ 18 декабря 2009

Вы получите ошибку типа «перегруженный метод отличается только типом возврата», если вы используете VC ++. Это связано с тем, что сигнатуры методов / функций не включают тип возвращаемого значения. Я предполагаю, что это из-за неоднозначности, которую это может вызвать, если возвращаемое значение не присваивается чему-либо например,

int iMyvar = object.method (); // очевидно, какой тип должен быть возвращен

Контрастность с: -

object.method (); // какую перегрузку вызовет компилятор, если тип возвращаемого значения будет частью сигнатуры? Ambiguos.

1 голос
/ 18 декабря 2009

Что касается переопределения, то оно относится к классовой наемной работе и позволяет достичь полиморфизма во время выполнения.

class Abstract
{
   public :  
   virtual Abstract* Clone() const = 0;
};

class Concrete1 : public Abstract  
{
   public :  
   Concrete1* Clone() const { return new Concrete1(*this); }
};

class Concrete2 : public Abstract  
{
   public :  
   Concrete2* Clone() const {  return new Concrete2(*this); }
};

Перегрузка между областями невозможна в соответствии со стандартом C ++.

1 голос
/ 18 декабря 2009

Нет, есть кое-что подобное, что вы можете сделать, например, введите возвращаемое значение (возможно, со специализациями) и укажите тип шаблона при вызове, например,

template<T>
T Foo()
{
  return 0;
}

template<>
double Foo<double>()
{
  return 3.14;
}

int i = Foo<int>(); // 0
double d = Foo<double>(); //3.14
1 голос
/ 18 декабря 2009

К сожалению, возвращаемое значение не является частью подписи, поэтому нет.

1 голос
/ 18 декабря 2009

Перегрузка только с изменением возвращаемого значения невозможна.

рассмотрим это:

Base->Foo();

вызывается без присваивания возвращаемого значения, тогда компилятор не может определить, какой метод вызывать. Ключевое слово

virtual используется для создания VTable и, тем самым, доказательства динамического полиморфизма Это не влияет на методы перегрузки.

...