我正在尝试编写在Windriver linux(64位)上运行的C ++应用程序。这是类似的代码:(我的代码的某些部分是自动生成的,我尽力使其保持相似)
#include <stdio.h>
class OneClass{
const void *data;
public:
OneClass(const void *inData){
printf("In normal const %u addr: %u\n", *((unsigned int*)(inData)), inData);
data = inData;
}
OneClass(){
printf("In default const\n");
data = NULL;
}
OneClass(const OneClass &in){
printf("In copy const\n");
data = in.data;
}
const void* getData(){return data;}
};
OneClass create(const unsigned &in){
printf("In create before %u\n", in);
return new OneClass(&in);
}
main()
{
OneClass two = create(100);
unsigned int *value = (unsigned int*)two.getData();
printf("In main %u\n", *value);
}
输出是:
In create before 100
In normal const 100 addr: 4294339016
In normal const 4294339016 addr: 134520840
In main 4294339016
我预计two.data是100,但它不是真的。怎么样?我还混淆了普通构造函数如何调用两次而不是复制构造函数?
任何人都可以帮助我吗?
答案 0 :(得分:3)
在OneClass(const void*)
函数中隐式调用构造函数create
。这是C ++的一个功能,允许隐式对象转换。
create
的返回类型为OneClass
。但是,您返回new OneClass(&in)
。这是指向对象的指针,而不是对象本身(它的类型是OneClass*
)。此指针传递给OneClass(const void*)
构造函数,另一个OneClass
使用OneClass*
指针创建。这就是你的构造函数被调用两次的原因。
使用explicit
关键字限定单个参数构造函数总是一个好主意,如下所示:
explicit OneClass(const void *inData)
现在,这段代码
OneClass create(const unsigned &in){
printf("In create before %u\n", in);
return new OneClass(&in);
}
将导致编译器错误,您可以捕获这样的细微错误。
此修订后的代码有效:
#include <cstdio> // you shouldn't include <stdio.h>, that's for C, not C++
class OneClass{
const void *data;
public:
explicit OneClass(const void *inData){
printf("In normal const %u addr: %p\n", // use the %p specifier to print pointers
*((unsigned int*)(inData)), inData);
data = inData;
}
OneClass(){
printf("In default const\n");
data = NULL;
}
OneClass(const OneClass &in){
printf("In copy const\n");
data = in.data;
}
const void* getData(){return data;}
};
OneClass* create(const unsigned &in){
printf("In create before %u\n", in);
return new OneClass(&in);
}
int main()
{
OneClass* two = create(100);
unsigned int *value = (unsigned int*)(*two).getData();
printf("In main %u\n", *value);
}
或者放弃动态内存分配(可能非常麻烦,非常快)使用它:
OneClass create(const unsigned &in){
printf("In create before %u\n", in);
return OneClass(&in);
}
int main()
{
OneClass two = create(100);
unsigned int *value = (unsigned int*)two.getData();
printf("In main %u\n", *value);
}
我建议你使用第二个。除非您特别需要使用new
分配内容,否则您不应该这样做。
答案 1 :(得分:1)
问题是create
函数,您似乎来自Java或C#背景,并将这些语言中的习语带到C ++,这些习惯用法在C ++中的工作方式与它们不同用Java或C#做。
在C ++中,您不需要使用new
来创建对象实例,new
所做的是分配内存并向其返回指针。以下是您遇到的问题:从create
返回的对象使用您通过执行new OneClass(...)
分配的指针进行初始化。
简单的解决方案是删除new
运算符:
return OneClass(...);