首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • new只是申请了一段内存空间,却没有调用构造函数初始化对象。下面的情况怎样才能调用构造函数呢? [已结贴,结贴人:dacai_1234]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dacai_1234
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 揭贴率:
    发表于:2008-08-21 00:29:23 楼主
    #include <iostream>
    using namespace std;
    #include"student.h"
    //类声明:
    class student
    {
    private:
    int num;
    public:
    student();
    ~student();
    int getnum();

    };

    //成员函数实现:
    student::student()
    {
    int num = 100;
    }
    int student::getnum()
    {

    return num;
    }

    student::~student(){}


    //主函数:
    int main()
    {
    student *stu;
    stu = new student[];
    cout < < stu->getnum() < < endl;
    stu->student::student();
    cout < < stu->getnum() < < endl;
    return 0;
    }

    两次输出的结果都是-33606819,说明new分配了内存空间后没有调用构造函数进行初始化。
    怎样才能new以后调用构造函数初始化对象呢?
    我印象中new了空间之后就应该调用构造函数了,但现在看来不是这样。
    那new和构造函数之间又是什么关系呢?请各位指教。
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • mcgradysudi
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 00:40:261楼 得分:0
    构造函数里面的变量num不是student类的成员变量,局部变量屏蔽掉了成员变量
    student::student()
    {
    num = 100;
    }
    改成这样就行了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • richbirdandy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 00:42:372楼 得分:5
    怎么可能没有调用构造函数呢 除非遇到异常
    new操作符有两个动作
    1 调用operator new函数
    2 调用相关的构造函数
    遇到异常会回滚
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • richbirdandy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 00:45:243楼 得分:0
    lz记忆中的正确结论被个错误程序推翻了 呵呵 太粗心了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lzr4304061988012
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 00:48:534楼 得分:0
    有2个错误:
    (1)动态分配类类型数组时未有分配大小;
    stu = new student[]; -》stu = new student[2];
    (2)student::student()
    {
    int num = 100;
    } 这个构造函数将num定义为局部变量,覆盖了成员那个num,成员那个num并未初始化;

    C/C++ code
    #include <iostream> using namespace std; //类声明: class student { private: int num; public: student(); ~student(); int getnum(); }; //成员函数实现: student::student() { num = 100; } int student::getnum() { return num; } student::~student(){} //主函数: int main() { student *stu; stu = new student[2]; cout << stu->getnum() <<endl; return 0; }


    输出:100
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • kxiaopeng
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 02:02:275楼 得分:5

    #include <iostream>
    using namespace std;
    //#include"student.h"
    //类声明:
    class student
    {
    private:
    int num;
    public:
    student();
    student(int);
    ~student();
    int getnum();

    };

    //成员函数实现:
    student::student():num(0) //无参构造函数,通过初始化列表来消除垃圾数据
    {
    }
    student::student(int x)//我又定义了一个带一个参数的构造函数
    {
    num=x;
    }
    int student::getnum()
    {

    return num;
    }


    student::~student(){}


    //主函数:
    int main()
    {
    student *stu;
    stu = new student;//你这里大可不必写成stu=new student[];去掉[]即可
    //cout < < stu->getnum() < < endl;//这里有错,因为你只是声明了*stu,并没有初始化它,初始化一个类的对象只
                                    //能通过调用构造函数,stu本身是个指针,我们没有给指针提供的默认构造函数和自
                                    //写的构造函数,这样你只是返回申请的指针的地址,但它指向不明,是个野指针,
                                    //会返回垃圾数据,所以会输出-33606819
    student p=student(100);

    cout < <stu->getnum() < <endl;
    *stu=student();
    cout < <stu->getnum() < <endl;
    return 0;
    }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • kxiaopeng
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 02:08:116楼 得分:0
    int main()
    {
    student *stu;
    stu = new student;//你这里大可不必写成stu=new student[];去掉[]即可
    //cout < < stu->getnum() < < endl;//这里有错,因为你只是声明了*stu,并没有初始化它,初始化一个类的对象只
                                    //能通过调用构造函数,stu本身是个指针,我们没有给指针提供的默认构造函数和自
                                    //写的构造函数,这样你只是返回申请的指针的地址,但它指向不明,是个野指针,
                                    //会返回垃圾数据,所以会输出-33606819
    student p=student(100);

    cout < <stu->getnum() < <endl;
    *stu=student();
    cout < <stu->getnum() < <endl;
    return 0;
    }
    不好意思,不小心删掉了一行代码,在student p=student(100);和cout < <stu->getnum() < <endl;中间加上这行代码:*stu=p;或者stu=&p;,呵呵
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dacai_1234
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 04:25:287楼 得分:0
    多谢了,确实这个地方粗心了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dacai_1234
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 04:34:368楼 得分:0
    虽然经常来csdn,但是提问题还是第一次。想不到有这么多热心的朋友帮忙,非常感谢。
    kxiaopeng 兄弟还给我逐行耐心解释,多谢。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dacai_1234
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 05:06:569楼 得分:0
    刚才按照lzr4304061988012的做法,把对象数组的元素个数赋值stu = new student[2]也可以输出100了。
    我就很奇怪,因为我原来是用while循环动态创建对象数组,相当于每循环一次创建一个对象,但运行不了。而这样赋值以后就可以运行了。为什么对象数组元素个数赋初值以后(赋值为1也可以),构造函数就可以将每个对象初始化了?这样就不是野指针了,不明白。

    {这次还有一个收获,就是第一次这样用指针 stu->student::student(); cout < < stu->getnum() < < endl;
    我把函数里面的int去掉以后,这一句也可以输出100}
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ymntomyimi8855
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 07:25:0710楼 得分:0
    你对构造函数不够了解,基础太差了!你要知道对象的生灭,构造函数是用来创建对象的,既然对象已经创建那么构造函数肯定被执行了,也就是先调用构造函数才能创建对象的;只要你执行了这个语句student *stu;
    stu = new student[12];动态分配数组对象是要指定大小,其次这是已经产生了12个对象指针,他调用了12次构造函数,这不是野指针,他有自己的地址,他也不会造成非法访问;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ymntomyimi8855
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 07:25:2211楼 得分:0
    你对构造函数不够了解,基础太差了!你要知道对象的生灭,构造函数是用来创建对象的,既然对象已经创建那么构造函数肯定被执行了,也就是先调用构造函数才能创建对象的;只要你执行了这个语句student *stu;
    stu = new student[12];动态分配数组对象是要指定大小,其次这是已经产生了12个对象指针,他调用了12次构造函数,这不是野指针,他有自己的地址,他也不会造成非法访问;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • yshuise
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 08:17:0712楼 得分:5
    楼上,你讲的只是其中一种情况,还有一种情况不调用构造函数。
    所以,这样:
    C/C++ code
    student* stu = (student*)malloc (12*sizeof(student)); for(int i = 0; i < 12; i++)new(&stu[i])student;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • iambic
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 4

      3

      3

    发表于:2008-08-21 08:41:3813楼 得分:0
    楼上的楼上讲的很好。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • yshuise
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 09:10:4914楼 得分:0
    只是楼主这种情况下,构造函数是必定调用。
    如果遇到下面的情况,构造函数是不被调用的:
    C/C++ code
    class{ public: string a; float b; };
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wjb_yd
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 09:59:0715楼 得分:0
    new数组只能调用默认构造函数
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dacai_1234
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 17:30:2716楼 得分:0
    引用 11 楼 ymntomyimi8855 的回复:
    你对构造函数不够了解,基础太差了!你要知道对象的生灭,构造函数是用来创建对象的,既然对象已经创建那么构造函数肯定被执行了,也就是先调用构造函数才能创建对象的;只要你执行了这个语句student *stu;
    stu = new student[12];动态分配数组对象是要指定大小,其次这是已经产生了12个对象指针,他调用了12次构造函数,这不是野指针,他有自己的地址,他也不会造成非法访问;


    你还没明白我的意思。如果我执行student *stu; stu = new student[];就如六楼所说:
    《因为你只是声明了*stu,并没有初始化它,初始化一个类的对象只能通过调用构造函数,stu本身是个指针,我们没有给指针提供的默认构造函数和自写的构造函数,这样你只是返回申请的指针的地址,但它指向不明,是个野指针,会返回垃圾数据,所以会输出-33606819》
    我也知道,既然student *stu; stu = new student[2];可以执行,那就一定是构造函数对他初始化了。
    我不明白的是为什么赋初值的情况下对象数组就有了自己的地址,尽管我知道这是一个事实。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dacai_1234
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 17:38:0417楼 得分:0
    引用 2 楼 richbirdandy 的回复:
    怎么可能没有调用构造函数呢 除非遇到异常
    new操作符有两个动作
    1 调用operator new函数
    2 调用相关的构造函数
    遇到异常会回滚

    2楼的说得很好。构造函数给变量初始化为他分配内存,而new也是为变量分配内存的,
    两者的本质和关系实在是理不清,一团麻似的。还请各位指教。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hmsuccess
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 18:07:5618楼 得分:5
    引用 12 楼 yshuise 的回复:
    楼上,你讲的只是其中一种情况,还有一种情况不调用构造函数。
    所以,这样:

    C/C++ codestudent* stu = (student*)malloc (12*sizeof(student));
    for(int i = 0; i < 12; i++)new(&stu[i])student;

    关键是当我们使用关键字new在堆上动态创建一个对象时,它实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。当然,如果我们创建的是简单类型的变量,那么第二步会被省略。
    例如:
    C/C++ code
    class A { int i; public: A(int _i) :i(_i*_i) {} void Say() { printf("i=%d\n", i); } }; //调用new: A* pa = new A(3); 那么上述动态创建一个对象的过程大致相当于以下三句话(只是大致上): A* pa = (A*)malloc(sizeof(A)); pa->A::A(3); return pa;


    原因在于new至少有三中含义:new operator、operator new、placement new
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • iambic
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 4

      3

      3

    发表于:2008-08-21 18:21:4319楼 得分:0
    谁说构造函数是分配内存的?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • iwong
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 22:55:2320楼 得分:0
    引用 14 楼 yshuise 的回复:
    只是楼主这种情况下,构造函数是必定调用。
    如果遇到下面的情况,构造函数是不被调用的:

    C/C++ codeclass{
    public:
    string a;
    float  b;
    };
    这个类也有默认构造函数,只是构造函数的初始化列表和函数体为空。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hauto
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-21 23:14:1921楼 得分:0
    补充一个错误:
    内存泄露。。。
    new分配后要delete
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • budTang
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 00:28:5122楼 得分:0
    [code=C/C++]
    #include <iostream>
    using namespace std;

    //类声明:
    class student
    {
    private:
    int num;
    public:
    student();
    ~student();
    int getnum();

    };

    //成员函数实现:
    student::student()
    {
    num = 100;
    }
    int student::getnum()
    {

    return num;
    }

    student::~student(){}


    //主函数:
    int main()
    {
    student *stu;
    stu = new student;
    cout < < stu->getnum() < <endl;


    return 0;
    }[code=C/C++]
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dacai_1234
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-23 00:40:1023楼 得分:0
    多谢各位了。终于可以结贴了。
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved