// ConsoleApplication34.cpp: 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> using namespace std; class A { public: int a; A(); }; A::A() { cout << "hello world!" << endl; } class CExample { private: int a; public: CExample() //定义过下边的自定义构造函数后,默认构造函数将不存在。因此需要重新写一遍 { a = 1; cout << "hello " << endl; } CExample(int b) { a = b; } CExample(const CExample& b) { a = b.a; } void Show() { cout << a << endl; } }; int main() { //不用new是在 栈 上定义的。 CExample test1; CExample test2 = CExample(); //new是在 堆 上定义的。 应使用delete释放内存 //有括号代表的是调用 含参构造函数CExample(int b) //无括号代表的是调用 无参构造函数CExample() 等价于 CExample* test3 = new CExample() CExample* test3 = new CExample(2); CExample* test4 = new CExample; //拷贝构造函数系列 CExample* test5(new CExample(6)); CExample test7(test1); CExample test6(); //错误 return 0; }
以上给出了常用的几种定义方法及区别。
注意:
1. 有new是在堆上 无new是在栈上,new 与 delete搭配使用。
2.有new的情况下,括号的作用是指定构造函数。无括号即使用默认构造函数
=============================================================================================
堆与栈上定义的详细区别:
from:http://blog.sina.com.cn/s/blog_586b6c050100dhjg.html
在C++里,有两种方法创建对象:
方法一:
ClassName object(param);
这样就声明了一个ClassName类型的object对象,C++会为它分配足够的存放对象所有成员的存储空间。
注意:为节省存储空间,C++创建对象时仅分配用于保存数据成员的空间,而类中定义的成员函数则被分配到存储空间中的一个公用区域,由该类的所有对象共享。
例如,我定义了一个这样的类:
class Rec
{
public:
Rec(int width,int height);
~Rec();
int getArea();
private:
int Rwidth;
int Rheight;
};
当你Rec myRec(5,5);这样创建一个myRec对象, 然后打印出sizeof(myRec);的时候,会得到 8 这个结果。
因为myRec中有2个int类型的数据成员,一个int成员占4个字节,所以myRec对象占8个字节。
这种方法创建的对象,内存分配是分配到栈中的,由C++缺省创建和撤销,自动调用构造函数和析构函数
注意:该方法创建的对象调用类方法时,必须用“.”,而不能用“->”.如myRec.getArea();
方法二:
ClassName *object=new ClassName(param);
delete object;
这种方法跟java有点类似,相同的是,它们都是在堆上分配内存来创建对象的(与上不同);不同的是,C++用new创建对象时返回的是一个对象指针,object指向一个ClassName的对象,C++分配给object的仅仅是存放指针值的空间。而且,用new 动态创建的对象必须用delete来撤销该对象。只有delete对象才会调用其析构函数。
注意:new创建的对象不是用“*”或“.”来访问该对象的成员函数的,而是用运算符“->”;
例如:Rec *rec=new Rec(3,4);
rec->getArea();
delete rec;
顺便提一下:
一般来说,编译器将内存分为三部分:静态存储区域、栈、堆。静态存储区主要保存全局变量和静态变量,栈存储调用函数相关的变量、地址等,堆存储动态生成的变量。 在c中是指由malloc,free运算产生释放的存储空间,在c++中就是指new和delete运算符作用的存储区域。
另外收集了两种方法的优点:
new出来的在堆上,直接定义的在栈上,栈的大小有限制
new的好处:
1、需要的时候才new(在复杂权限和业务逻辑系统中很重要)
2、对象可靠性检查(没有栈空间的限制问题)
3、对象的适度留用控制
=============================================================================================
new中的括号总结:
from:https://blog.csdn.net/wang13342322203/article/details/80807904
error:没有合适的默认构造函数可用 ,一般也是这个问题
括号分为两种,中括号[]或小括号()。
为方便说明,定义指针类型为class test, 指针为
test *ptest;
一、 中括号的情况。
中括号是用来标示申请的是一个对象,还是一组对象。
1 没有中括号时,即ptest = new test; 这时ptest得到的是一个对象*ptest, 释放时使用delete ptest;
2 带有中括号时,在中括号中需要有一个正整数参数。
ptest = new test[N];
N可以是变量,也可以是常量。
这时申请到的ptest指向的空间是N个连续的对象ptest[0],ptest[1]...ptest[N-1],即可以当做一个数组使用。
释放时需要调用delete [] ptest;
二、小括号的情况。
小括号是用来指定初始化参数,用于类指针时,就是指定调用哪个构造函数。
1 有小括号时,小括号中可以有若干参数,也可以没有参数。
比如
ptest = new test(); 这样在构造时就会调用无参构造test();
ptest = new test(1); 就会调用构造函数test(int),即一个整型参数的构造函数。
2 没有小括号时,默认调用无参构造。
即
ptest = new test;
和ptest = new test();是一样的。
===========================================================================================================================