【问题标题】:C++ Abstract class pointer in method方法中的 C++ 抽象类指针
【发布时间】:2021-05-26 17:35:15
【问题描述】:

所以我有一个 c++ 项目,我正在处理,我正在尝试理解其他人的代码,但我得到的只是关于 c++ 抽象类的错误和困惑。

所以我有一个头文件,一个cpp文件和一个主程序。

我想创建一个抽象类指针,然后将它传递给一个将其初始化为子类的方法,然后回到主程序中我可以将它用作子类:

ma​​in.cpp:

#include "a.h"
#include <iostream>

using namespace std;

void parse(A* a){
  a = new B();
  a->foo();
}

int main() {
  A* a;
  parse(a);
  a->foo();
}

a.h:

class A{
  public:
    virtual void foo() const = 0;
    virtual ~A(){ }
};

class B : public A{
  public:
    void foo() const override;
};

class C : public A{
  public:
    void foo() const override;
};

a.cpp

#include <iostream>
#include "a.h"

void B::foo() const{
  std::cout << "B" << std::endl;
}

void C::foo() const{
  std::cout << "C" << std::endl;
}

基本上在这里我认为我应该得到一个 B,但我得到一个 分段错误 或程序 退出 没有打印任何东西。

感谢您的帮助!

【问题讨论】:

  • void parse(A*&amp; a){ 应该可以解决您的问题。

标签: c++ initialization polymorphism abstract-class pass-by-reference


【解决方案1】:

在 main 中,您有未初始化的指针 a

int main() {
  A* a;
  parse(a);
  a->foo();
}

所以这个说法

  a->foo();

导致未定义的行为。

至于函数解析

void parse(A* a){
  a = new B();
  a->foo();
}

然后它处理它的局部变量a。更改局部变量不会影响 main 中声明的原始指针。

您需要将参数声明为具有引用类型

void parse(A* &a){
  a = new B();
  a->foo();
}

在这种情况下,main中声明的指针a将通过引用传递给函数,函数将改变原来的指针a。

【讨论】:

    【解决方案2】:

    除了 Vlad 的 answer 中描述的未定义行为问题之外,即使 main 中的指针已正确初始化,您的示例也会泄漏内存。

    我推荐一个替代解决方案。我建议不要使用拥有裸指针,而不是通过引用修改指针。相反,返回指针,并使用智能指针作为所有权:

    std::unique_ptr<A>
    parse(){
        auto a = std::make_unique<B>;
        a->foo();
        return a;
    }
    
    int
    main() {
        auto a = parse();
        a->foo();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 2013-07-08
      • 1970-01-01
      • 2011-03-20
      相关资源
      最近更新 更多