【问题标题】:Calling a function without taking allocation of object in c++在 C++ 中调用函数而不分配对象
【发布时间】:2013-05-01 14:49:04
【问题描述】:

是否可以在不分配内存的情况下使用引用运算符(->)调用函数。 我在某些情况下尝试过这段代码

Foo *fooObject;
fooObject->someFunction;

我对这件事感到困惑。这在 Dev C++ 中运行良好,但在 Visual C++ 中崩溃。

【问题讨论】:

  • 这不是有效的代码(实际上是未定义的行为)。这是没有意义的,因为 fooObject(指向 Foo 的指针)没有被初始化。它可以指向任何地方。如果你不想在堆上分配内存,你可以在堆栈上做例如: Foo fooObj; fooObj.someFunction().
  • “可能”是什么意思?您可以编写它(您的程序在可以编译的意义上是“格式良好的”),但正如 maverik 所说,它是未定义的行为。

标签: visual-c++ object dev-c++


【解决方案1】:

不,在没有分配内存的情况下,永远不可能使用 ->,因为该运算符试图取消引用指向对象的指针......因此该对象必须存在。

指向的对象必须存在……这是“内存分配”,可以在栈或堆上完成。

以下语法...

fooObject->func();

等价于

(*fooObject).func()

为了能够做到*fooObjectfooObject指向的对象必须存在。

在您的代码中

Foo *fooObject;

是一个悬空指针,因为你没有将它指向一个对象。指针值可能为 NULL 或指向某个完全随机的内存块:尊重它会导致您出现问题,因为无法保证您尊重的是什么……这称为 “未定义行为” .

要为您的对象分配内存,您可以像这样在堆栈上执行此操作

Foo fooObject;

然后,如果您愿意,可以使用指向对象的指针...

Foo *fooObjectPTR = &fooObject;

但请注意,分配在堆栈上的对象仅在其范围内时才存在。当它超出范围时,它会被销毁,并且您的指针将再次成为悬空指针,因此不能使用。

或者你可以像这样在堆上分配

Foo *fooObjectPTR = new Foo();

如果你在堆上分配,你必须小心以后使用delete释放分配的内存

【讨论】:

  • 我认为最好说你不能使用 -> 除非你的指针指向一个有效的对象。您可以将指针分配给基于堆栈的变量。富 *fooPTR; Foo foo_stk_obj; fooPTR = &foo_stk_obj;
  • @Freddy ...是的,明白你的意思...通过“内存分配”我的意思是堆或堆栈,但你是对的,它可能更清楚...更新答案,谢谢
【解决方案2】:

您可以在没有实例实际存在的情况下在类上调用静态函数,但是这是通过使用 :: 表示法完成的,然后该函数在任何特定实例的范围之外运行 - 类的静态成员函数没有隐含的this 指针:

class Foo {
public:
  static void someFunction(void) {std::cout << "BOO!\n";};
};

...
int main(...) {
  Foo::someFunction();
  return 0;
}

[class-static] 中的标准状态:“静态成员可以 使用类成员访问语法来引用, 在这种情况下对象表达式 总是被评估。”

与此相反,Microsoft documentation 声明:The left side of a member-selection operator (. or –&gt;) that selects a static member function is not evaluated,这意味着以下内容适用于 VC++,但不适用于符合标准的 C++:

Foo* not_allocated;
not_allocated->someFunction();

【讨论】:

  • 标准对此有何评论:“后缀表达式后跟一个点 . 或箭头 -&gt; [...],然后是一个 id 表达式,是后缀表达式. 计算点或箭头之前的后缀表达式;"带有脚注“如果对类成员访问表达式求值,即使结果对于确定整个后缀表达式的值是不必要的,也会发生子表达式求值,例如,如果 id 表达式表示静态成员。” [expr.ref]/1
  • 也许更重要的 (?) 是 [class.static],它指出“可以使用类成员访问语法来引用静态成员,在这种情况下,始终评估对象表达式”。我会更新我的答案。
猜你喜欢
  • 2011-11-25
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多