从函数返回抽象类

发布于 2024-09-01 16:31:32 字数 33 浏览 6 评论 0原文

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

Is it possible to return an abstract class(class itself or a reference, doesn't matter) from a function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

烟沫凡尘 2024-09-08 16:31:32

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

A * f() {
    return new B;
}

或引用:

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

或智能指针:

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

You can return an abstract class pointer - assuming B is a concrete class derived from abstract class A:

A * f() {
    return new B;
}

or a reference:

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

or a smart pointer:

std::unique_ptr<A> f() {
    return std::make_unique<B>(...);
}
独守阴晴ぅ圆缺 2024-09-08 16:31:32

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

但是,您无法返回实际抽象类的实际实例,因为根据定义,您无法实例化它。但是,您可以返回具体子类型的实例,这已经足够好了,因为根据替换原则,您应该始终能够使用子类型而不是超类型。

You can declare the return type to be a reference or pointer to the abstract class, so that it can be assigned to references or pointers to the abstract class and used based on its interface.

However, you cannot return an actual instance of the actual abstract class because by definition you cannot instantiate it. You could, however, return instances of concrete subtypes which is good enough because by the principle of substitution, you should always be able to use a subtype instead of a supertype.

一百个冬季 2024-09-08 16:31:32

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

No, but a function could have a return type of a pointer (or a reference) to an abstract class. It would then return instances of a class that is derived from the abstract class.

娜些时光,永不杰束 2024-09-08 16:31:32

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

Abstract classes cannot be instantiated and thus not returned.

不知所踪 2024-09-08 16:31:32

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;
}

永远无法返回实际的抽象基类对象,因为永远不会存在某个抽象类对象的实例抽象基类。可以像上面的示例一样返回对抽象基类型的指针和引用。

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

The Factory design pattern is an example of returning a pointer to an abstract class object:

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;
}

An actual abstract base class object can never be returned since there can never be an instance of an abstract base class. Pointers and references to an abstract base type can be returned as in the above example.

Pointers and references to an abstract base class returned from a function or method actually refer to a descendant of the abstract base type.

逆流 2024-09-08 16:31:32

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

你唯一需要担心的是,如果你按点返回,调用者是否会拥有该对象并释放,如果你按引用返回,请小心返回函数的局部变量,它编译得很好,但会崩溃。函数局部变量会在函数调用后被释放,如下面的代码,它会在“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;
}

You can't return abstract class itself in the funtion return, but abstract class point and abstract class reference are both OK.

The only thing you need to worry is if you return by point, will the caller own the object and release, if you return by reference, be careful to return funtion's local variable, it compiles fine but it will crash. The function local variable will be released after the function call, like the following code, it will crash at line "a.print();". Hopefully it make sense.

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;
}
时光匆匆的小流年 2024-09-08 16:31:32

基于@stakx的答案,我更喜欢将智能指针方法作为默认值:

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

虽然其他两种方法都是可行的(返回原始指针或返回引用),但这具有简化调用代码中的内存管理的巨大优势。

Building on the answer from @stakx, I prefer the smart pointer approach as the default:

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

While the other two approaches are viable (returning a raw pointer or returning a reference), this has the big advantage of simplifying memory management in the calling code.

青衫负雪 2024-09-08 16:31:32

我知道我有点晚了,但我希望这会对某人有所帮助...

作为 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;
  }
}

接受任何批评!

I know I'm little late but I hope this will help someone...

Being a newbie in C++ programming, I've also been stuck for a while on that problem. I wanted to create a factory method that returns an reference to an abstract object. My first solution using pointers worked well but I wanted to stay in a more "C++ manner". Here is the code snippet I wrote to demonstrate it:

#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;
  }
}

Open to any critism !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文