为什么C ++ new没有返回指向它创建的对象的指针?

时间:2014-10-08 17:38:56

标签: c++ oop

我理解下面的代码,据我所知,当我使用new声明一个对象时,它构造一个特定类型的对象并返回指向该对象的指针。但是当我使用new创建一个student对象时,它不会返回指向该对象的指针。此外,当我打电话给新学生(s1)时,“学生(学生*)”被调用,而不是给出错误,例如没有从学生到学生的类型转换*

#include <bits/stdc++.h>

using namespace std;

class student {
    public:
        int cool;

        student(student* s){ // this constructor is taking pointer to s whereas i am calling it by value below
            this->cool=s->cool;
        }
        student(){
            this->cool=1;
        }
};
void blah(student s){
    printf("cool:%d\n",s.cool);
}

int main(){

    student s1=new student(); // here new is not returning student*
    s1.cool=2;
    student s2=new student(s1); // here we are passing s1 which of type student but constructor (student*) is called why ???
    blah(s2);
}

以下是输出我没有任何错误:

  

凉爽:2

3 个答案:

答案 0 :(得分:7)

你正在泄露记忆。

这个构造函数:

student(student* s)

用于隐式地满足转换,因为它未标记为explicit。那么这里发生了什么:

student s1=new student();

您是堆 - 分配新的student对象吗? new表达式求值为指针。当编译器查看分配时,它知道分配不起作用,因为s1student,并且您正在为其分配student *。所以它寻找一种方法来转换它并找到我上面提到的构造函数。

所以你所做的相当于:

student s1 = student(new student());

由于你永远不会delete指针,所以堆分配会被泄露,但是从你的角度看你的程序正确执行。

如果您将转换构造函数标记为:

explicit student(student* s)

然后编译器不会自动使用此构造函数进行转换,需要显式调用某种类型,而行student s1=new student();确实会导致编译时错误,同时允许student s1 = student(new student());工作(但当然它仍会导致内存泄漏。)

答案 1 :(得分:2)

new正在返回指向student的指针。当然是!

第一种情况发生的是student s1 = new student()行正在调用student(student*)构造函数来构造s1

在第二种情况下,行student s2 = new student(s1)首先调用默认的复制构造函数,然后调用student(student*)构造函数来构造s2

在这两种情况下,都会发生内存泄漏,因为您没有致电delete来匹配new

这种行为是为什么在单个参数构造函数之前使用explicit是一个非常好的主意,除非你真的想要这种隐式转换(并且,即使你认为你做了,你可能不会)。

答案 2 :(得分:1)

我不知道你在哪里得到new没有返回指针的奇怪想法。您发布的代码不以任何方式支持该声明。这个初始化

student s1 = new student();

使用student创建默认构造的 new对象。然后new返回的指针将传递给student::student(student *)构造函数,因为它应该是。

第二次初始化

student s2 = new student(s1);

使用student创建复制构造的 new对象。然后new返回的指针将传递给student::student(student *)构造函数,因为它应该是。

为什么您认为第二种情况中的“从studentstudent *的无类型转换”错误并不明确。您的student类具有由编译器声明和定义的隐式复制构造函数。这是student(s1)初始化中使用的构造函数。此处无需进行任何studentstudent *转换,也无需出错。

在这两种情况下,student::student(student *)都会被new返回的指针调用。看来您出于某种原因认为在第一种情况下student::student(student *)未被调用。但这是一个完全没有根据的信念。它叫做。