c++ - C++ 中对象实例化的方法访问

标签 c++ inline

在main函数中,我以两种方式调用了send函数。我想知道两者之间有什么区别。调用了哪些构造函数,在这两种情况下如何复制数据?当我以第一种方式调用它时,我在发送数据时得到了不同的值。当我删除 OneClass(OneClass *) 的内联时,问题得到了解决。

#include <iostream>
class OneClass{

 const void *data;
 public:
  inline OneClass(const void *inData);

  OneClass(const OneClass &in){
         data = in.data;
   }

   static OneClass create(const unsigned &in);
   void send();
};

OneClass OneClass::create(const unsigned &in){
   return OneClass(&in);
}

inline OneClass::OneClass(const void *inData):data(inData){
}

void OneClass::send(){
   std::cout<<"send: "<<*((int*)data)<<"\n";
}


main()
{
  int var = 100;
  OneClass one = OneClass::create(var);
  one.send();//I get different value than 100 in cout(On windriver 64bit)

  OneClass::create(var).send();

}

最佳答案

调用哪些构造函数以及复制什么内容并不相关。你有未定义的行为。内联声明也是无关紧要的,它只是碰巧改变了未定义的行为。

未定义行为的原因如下:

OneClass OneClass::create(const unsigned &in){
   return OneClass(&in); // <-- here you take the address of the referenced integer
}

好的,你获取了一个对象的地址。为什么这么糟糕?正因为如此:

OneClass::create(100);

整数文字已绑定(bind)到引用in。当您将文字绑定(bind)到引用(必须是 const)时,会创建一个临时值。 create 调用结束后,临时对象不再存在。该地址存储在成员变量中,稍后使用它会导致未定义的行为。

但是,在第二种情况下:

OneClass::create(100).send();

send() 在创建临时对象的同一完整表达式中调用。因此,临时对象仍然存在,并且对象内的指针仍然有效,并且您不会得到未定义的行为。

由于 OneClass 的实例存储对象的地址,因此必须确保其存储地址的任何对象存在的时间比该实例的存在时间长。您可能应该将 create 的参数类型更改为指针,以便调用者知道发生了什么并且不会尝试传递文字。


编辑:更新

如果参数是 int 变量,而不是文字,则上述内容仍然适用,因为当 int 绑定(bind)到 const unsigned&< 时会创建临时变量。如果您将参数类型更改为 const int& 并使用了使用指针时作用域内的变量,则将定义行为。

关于c++ - C++ 中对象实例化的方法访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33916163/

相关文章:

c++ - 可变参数模板特化,std::enable_if,SFINAE

c++ - wxCheckListBox 过滤函数

html - 为什么内联网格在 Safari 中不起作用?

javascript - 内联JS不以html形式调用

c++ - 如何从 C 程序调用 bash shell 脚本中定义的函数

c++ - 将多个文本文件从一个文件夹复制到 C++ 中的不同文件夹

c++ - 将 BSTR 转换为 int

html - 通过内联 CSS 加载外部字体

c++ 17内联+ thread_local vs thread_local

c - 与一般内联相比,为什么 gnu_inline 属性对代码生成的影响如此之大?