【问题标题】:Calling a virtual function of in-memory object调用内存对象的虚函数
【发布时间】:2014-06-02 10:52:45
【问题描述】:

我正在尝试为具有虚函数的类创建内联构造函数。 总体而言,该函数必须是虚拟的,因为 Shape::print 将被另一个类调用,不知道它正在处理哪种(确切类型)Shape。

我看到这一定是某种与内存相关的问题。当使用我的类对象不是构造但作为指针时,如何调用此函数?还是我错过了什么?

#include <stdio.h>
#include <stdlib.h>

using namespace std;

class Shape {
public:
    virtual void print(){};
};

class Circle : Shape {
private:
    int r;
public:
    Circle(int radius){
        this->r = radius;
    }

    // My "inline-constructor"
    static Circle* make(int radius){
        Circle* circ = (Circle*) malloc(sizeof(Circle));
        circ->r = radius;
        return circ;
    };

    virtual void print(){
        printf("%u", this->r);
    };
};

int main(){
    Circle circObj(5);
    circObj.print(); // Works fine    
    Circle* circPtr = Circle::make(10);
    circPtr->print(); // Crashes    
    return 0;
 }

提前致谢,如有任何帮助,我们将不胜感激。

【问题讨论】:

  • “内联构造函数”更好的名称是“工厂函数”
  • 如果我调用(new Circle(10))-&gt;print(); 之类的东西,之后对象不会从内存中删除吗?
  • 另外,在每个malloc 之后应该调用free,在每个new 之后应该调用delete 以避免内存泄漏。或者使用智能指针。

标签: c++ class pointers virtual


【解决方案1】:

在你的“inline-constructor”中,你只是分配内存,而不是初始化它。例如,vtable 未初始化,导致崩溃,因为print 是虚拟的,并且它的地址应在 vtable 中。

尝试使用Circle* circ = new Circle(radius); 而不是malloc

【讨论】:

    【解决方案2】:
    // My "inline-constructor"
    static Circle* make(int radius){
        Circle* circ = (Circle*) malloc(sizeof(Circle));
        circ->r = radius;
        return circ;
    };
    

    这不是任何一种构造函数。这只是一个错误编写的工厂方法。它应该只包含

    return new Circle(radius);
    

    这使得它变得如此微不足道,以至于完全没有意义。

    当使用我的 Class-Object 不是构造而是作为指针时,如何调用此函数?

    Shape* shape = ....; // for example, new Circle(...)
    shape->print();
    

    没有火箭科学

    【讨论】:

    • 感谢您的帮助!
    【解决方案3】:

    问题是,malloc 只是分配了足够的 raw 内存并将其返回。 malloc 不会初始化创建的内存。因此,您的对象成员必须在使用前手动初始化。您只为r 这样做,而不是为成员方法print

    您应该使用new 而不是mallocnew 分两步工作

    1. 使用 operator new 分配足够的内存(malloc 的等效任务)
    2. 调用对象的构造函数对其进行初始化,这实际上是为成员设置值。

    【讨论】:

    • 谢谢,我要自己记住这个;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 2021-03-11
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 2010-10-27
    相关资源
    最近更新 更多