从函数返回一个抽象类

时间:2010-05-18 21:27:15

标签: c++ abstract-class

是否可以从函数返回抽象类(类本身或引用,无关紧要)?

7 个答案:

答案 0 :(得分:33)

您可以返回一个抽象类指针 - 假设B是从抽象类A派生的具体类:

A * f() {
    return new B;
}

或参考:

A & f() {
    static B b;
    return b;
}

或智能指针:

std::unique_ptr<A> f() {
    return std::make_unique<B>(...);
}

答案 1 :(得分:16)

您可以声明返回类型作为抽象类的引用或指针,以便可以将其分配给抽象类的引用或指针,并根据其接口使用。

但是,您无法返回实际抽象类的实际实例,因为根据定义您无法实例化它。但是,您可以返回具体子类型的实例,这是足够好的,因为principle of substitution,您应始终能够使用子类型而不是超类型。

答案 2 :(得分:4)

不,但函数可以具有指向抽象类的指针(或引用)的返回类型。然后它将返回从抽象类派生的类的实例。

答案 3 :(得分:3)

抽象类无法实例化,因此无法返回。

答案 4 :(得分:1)

Factory 设计模式是返回指向抽象类对象的指针的示例:

class Base
{ ; }

class One : public Base
{ ; }

class Two : public Base
{ ; }

Base * Factory(unsigned int number)
{
  Base * p_item(NULL);
  switch (number)
  {
    case 1:
      p_item = new One;
      break;
    case 2:
      p_item = new Two;
      break;
    default:
      p_item = NULL;
      break;
  }
  return p_item;
}

永远不会返回实际的抽象基类对象,因为永远不会有抽象基类的实例。可以返回指针和对抽象基类型的引用,如上例所示。

从函数或方法返回的指针和对抽象基类的引用实际上是指抽象基类型的后代。

答案 5 :(得分:1)

您不能在函数返回中返回抽象类本身,但是抽象类点和抽象类引用都可以。

您唯一需要担心的是,如果按点返回,调用者将拥有对象并释放,如果按引用返回,请小心返回funtion的局部变量,它可以很好地编译但会崩溃。函数局部变量将在函数调用后释放,如以下代码所示,它将在“ a.print();”行崩溃。希望这是有道理的。

class A {
public:
  virtual void print() = 0;
};

class B : public A {
    
    public:
    void print()
    {
        cout << "print";
    }
    
    A& GetA() {
        
        B b;
        return b;
    }
};

int main()
{
    cout<<"Hello World";
    
    B b;
    A &a = b.GetA();
    a.print();
    return 0;
}

答案 6 :(得分:-5)

我知道我迟到了,但我希望这能帮助别人......

作为C ++编程的新手,我在这个问题上也被困了一段时间。我想创建一个返回对抽象对象的引用的工厂方法。我使用指针的第一个解决方案运行良好,但我希望保持更加“C ++方式”。这是我为编写它而编写的代码片段:

#include <iostream>

using std::cout;
using std::endl;

class Abstract{
public:
  virtual void foo() = 0;
};

class FirstFoo: public Abstract{
  void foo()
  {
    cout << "Let's go to the foo bar!" << endl;
  }
};

class SecondFoo: public Abstract{
  void foo()
  {
    cout << "I prefer the foo beer !" << endl;
  }
};

Abstract& factoryMethod(){
  static int what = 0;

  if(what++ % 2 == 0)
    return *(new FirstFoo());
  else
    return *(new SecondFoo());
}

int main(int argc, char* argv[])
{
  int howMany = 10;
  int i = 0;

  while(i++ < howMany)
  {
    Abstract& abs = factoryMethod();
    abs.foo();
    delete &abs;
  }
}

对任何批评都开放!