【问题标题】:sizeof C++ class from static member functionsizeof C++ 类来自静态成员函数
【发布时间】:2013-08-11 02:21:41
【问题描述】:

我正在尝试编写一段 C++ 代码,从静态类成员中分配一个类的实例,同时让它知道任何继承的子类的大小

.h 文件

class MyObject {
    int toastNumber;
    static MyObject *allocate();
}
class MySubclass : public MyObject {
    int NSABackdoor;
    int someOldFunction();
}

.cpp 文件

#include ".h file"

MyObject *MyObject::allocate() {
    return (MyObject *)calloc(1, sizeof(this)); // error here
}

int MySubclass::someOldFunction() {
    return 6;
}

main.cpp 文件

#include other files
int main() {
    MySubclass *instance = MySubclass::allocate();
    return 0;
}

在尝试编译代码时,g++ 会吐出类似的错误

MyObject.cpp: In static member function ‘static MyObject* MyObject::allocate()’:
MyObject.cpp:5:47: error: ‘this’ is unavailable for static member functions

可以像这样从成员函数中分配实例吗? 我不能只使用 sizeof(MyObject) 因为那会破坏继承。 我知道这可以通过宏来完成,但我更喜欢它作为类函数。

谢谢

--

凯兰

【问题讨论】:

  • 不要在 C++ 中使用 calloc(使用 new),并且不能在静态成员函数中使用 this,这是没有意义的。 sizeof(MyObject) 会起作用。
  • @Borgleader 他试图从this 获取类名而不是对象。但是是的,因为 C++ 不支持这个,所以不起作用。
  • 您是否偶然将staticvirtual 混淆了?

标签: c++ class inheritance sizeof member


【解决方案1】:

如果你坚持这样做,你应该使用模板,如下所示。

template <class SubClass>
static SubClass* allocate();

template <class SubClass>
SubClass *MyObject::allocate() {
    return (SubClass *)calloc(1, sizeof(SubClass));
    //or return new SubClass();  // this is better and is the C++ way
}

请注意,使用calloc 可能会导致进一步的问题,首先是它不会调用构造函数。

我还假设您的意思是 malloc,因为 calloc 似乎是用于数组的。

那你就叫它

MySubclass *instance = MyObject::allocate<MySubclass>();

您的代码不起作用,因为 C++ 没有“自我类型”的概念

【讨论】:

  • C++ 的方式是根本不使用new
  • 这是不必要的复杂,它使用 calloc。
  • 这是唯一真正理解这个问题的人。 -- 等等,没关系,这不是我认为的解决方案
  • @Borgleader 完整阅读了这个问题,也许您可​​以看到复杂性的原因,至于calloc,我通常会先尝试解决问题,然后再提出进一步的建议(在下一行)
  • 没关系,我没关系。我更多地考虑从模板函数返回基类指针。这样,如果您尝试使用不是子类的类来调用它,就会出现错误。但我想这取决于您希望在哪里捕获错误。
【解决方案2】:

错误信息很清楚。静态成员函数不属于任何特定对象,只能访问类的静态数据成员。这就是为什么您不需要类实例来调用静态成员函数的原因。

你可以试试-

MyObject *MyObject::allocate() {
    return new MyObject();
}

记得删除资源。

【讨论】:

  • 您的代码有效,并且似乎具有子类意识。谢谢你。如果我还可能问,有没有办法subclass *i = subclass::allocate() 而不强制转换为子类?因为 ::allocate 返回一个 MyObject。
  • @KaelanDuck:你说它是“子类感知”是什么意思?无论从哪个类调用它,它都会分配一个MyObject 对象。
  • 这不是子类感知
  • @BenjaminLindley 我的意思是我可以访问子类的所有成员,即使我似乎正在分配一个 MyObject
  • @KaelanDuck:我不知道你用什么代码来确定,但这是错误的。
【解决方案3】:

首先,你不应该使用 calloc,而应该使用 new
二、可以使用sizeof(MyObject)
第三,即使 this 可用,sizeof(this) 是指向对象的指针的大小,而不是对象本身

【讨论】:

    【解决方案4】:

    看起来你想要做的是覆盖operator newMyClass 及其派生类:

    class MyObject {
        int toastNumber;
        static void* operator new(std::size_t size) {
            void* ptr = ::operator new(size);
            std::cout << "Allocated " << size << " bytes at address "
                      << ptr << '\n';
            return ptr;
        }
    };
    

    编译器根据您分配的是实际的MyClass 还是更大的派生类传递正确大小的块进行分配。请注意,它并没有您想象的那么有用。

    你想用这个做什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多