C++构造,析构,友元类,对象,static成员,复制构造函数,运算符重载杂谈
2014-12-25 00:43
543 查看
1.
构造函数初始化分配内存
析构函数清空数据,释放内存
2.
友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
3.友元函数
友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。
对象的创建
Static成员
复制构造函数
拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。
一般格式 类名(const 类名 &s)//
通过已经存在的对象来初始化自己
Const限定传入的参数在复制构造函数不被修改
浅复制与深复制区别
浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
简单的说就是
简单运算符重载
友元函数实现重载(友元函无this指针)
构造函数初始化分配内存
析构函数清空数据,释放内存
#include<stdlib.h> #include<iostream> class create { int *p; public: create(int n)//析构函数初始化分配内存 { p = new int ; for (int i = 0; i != n; i++) { p[i] = i; std::cout << p[i] << std::endl; } } ~create()//析构函数清空数据,释放内存 { delete[]p; } }; void main() { create K(16); system("pause"); }
#include<iostream> class circle { public: double R; public: circle(double r)//默认空构造函数但如果定义了构造函数,必须使用这个构造函数 { R = r; } public: void setR(double r) { R = r; } double area() { return R*R*3.1415; } }; void maian() { int a = 5; int b(5); std::cout << a << std::endl; std::cout << b << std::endl; system("pause"); } void mainfasasd() { /*circle A;无构造函数或者构造函数默认为空 A.setR(10); std::cout << A.area() << std::endl; system("pause");*/ circle B(100); //调用构造函数 也是初始化一个B的对象,必须这样做 std::cout << B.area()<< std::endl; system("pause"); }
2.
友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
include<iostream> class A { friend class B;//与B可以共用a的函数和数据 private: int x; public: void printx() { std::cout << x << std::endl; } }; class B { private: A obj;//创建一个A类的对象 public: void setx(int a) { obj.x = a; obj.printx(); } }; int mai111111n() { //A A1; //A1.printx(); B b; b.setx(100); system("pause"); return 0; }
3.友元函数
友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。
#include<iostream> class OO { friend void fun(OO *p, int a);//声明友元函数, friend void funA(OO&OOA, int a);//声明了友元函数,这个函数可以访问私有 int x; public: void printx(int a) { x = a; std::cout << x << std::endl; } }; //注意友元函数无this指针 void fun(OO *p, int a) { p->x = a;//访问private成员 std::cout << p->x<< std::endl; } void funA(OO&OOA, int a) { OOA.x = a;//友元函数访问private成员 std::cout << OOA.x<< std::endl; } void main() { OO OO1; OO1.printx(100); fun(&OO1, 1002); funA(OO1, 1000); system("pause"); }
对象的创建
include<iostream> class M { int a, b; public: M(int x, int y) { a = x; b = y; } void seta(int x) { a = x; std::cout << a << std::endl; } void setb(int y)const //强调不可以修改类的内部成员变量 { //b = y;无法修改 const限定了 std::cout << b << std::endl; } }; void ma1111in() { M text(2, 4); text.seta(1); system("pause"); }
Static成员
#include<iostream> class simple { int x, y; static const int z =1; static int u;//在外部初始化 public: simple(int a, int b, int c) { x = a; y = b; this->u = c; } void printu() { std::cout << this->u << std::endl; } static void printAB()//静态,不依赖与对象,可以直接运行 { std::cout << "asdfasf" << std::endl; } }; int simple::u(10);//外部初始化 void main() { simple A(1, 2, 3); A.printu(); A.printAB(); system("pause"); //simple::printu();不合法,合法,依赖对象 simple::printAB();//合法,不依赖与对象,可以直接运行 system("pause"); }
复制构造函数
拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。
一般格式 类名(const 类名 &s)//
通过已经存在的对象来初始化自己
Const限定传入的参数在复制构造函数不被修改
#include<stdlib.h> #include<iostream> class TTTT { int a; public: TTTT(int x) { a = x; std::cout << a << std::endl; } TTTT(const TTTT &s)//通过已经存在的对象,初始化自己 { //限定s这个时候不可以修改 a = s.a; std::cout << a << std::endl; } }; void ma11111in() { TTTT A1(6); TTTT A2(A1); system("pause"); }
浅复制与深复制区别
浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
简单的说就是
//浅复制是直接复制指针的地址,共用一段内存 //深复制,就是各自用各值得内存 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> //深拷贝就是除了一般复制,还保存内存复制 //浅拷贝就是一般复制,只指针复制,这样会使2个对象的指针指向同一片内存区域 class name { public: name(char *pn);//成员函数申明 ~name();//析构函数声明 name(const name &obj);//复制析构函数声明 void printname() { std::cout << pname << std::endl; } private: char *pname; int size; }; name::name(char *pn) { std::cout << "构造函数创建" << std::endl; pname = new char[strlen(pn) + 1]; if (pname != 0) { strcpy(pname, pn); size = strlen(pn); } } name ::~name() { std::cout << "销毁" << pname << std::endl; pname[0] = '\0'; delete[]pname; size = 0; } name::name(const name &obj) { pname = new char[strlen(obj.pname) + 1]; if (pname != NULL) { strcpy(pname, obj.pname); } size = obj.size; //上面是深复制 //浅复制则是 pname=obj.pname指向同一内存地址 } void main() { name obj1("abcd"); obj1.printname(); name obj2(obj1); obj2.printname(); system("pause"); }
简单运算符重载
#include<iostream> //x+yi 复数++,-- class fushu { private: int x; int y; public: fushu() { } fushu(int a, int b)//构造函数 { x = a; y = b; } void printfushu() { std::cout << x << "+" << y << "i" << std::endl; } fushu operator ++() { x++; y++; return *this;//返回自己 } fushu operator --() { x--; y--; return *this; } fushu operator =(fushu b) { x = b.x; y = b.y; return *this; } ~fushu() { } fushu operator +(fushu a)//实现复数加法 { fushu temp(0, 0); temp.x = x + a.x; temp.y = y + a.y; return temp; } fushu operator()() { } }; int mai11111n()//main函数无法重载 { fushu A(3, 5); A.printfushu(); A++;//重载 A.printfushu(); A--;//重载 A.printfushu(); fushu B; B = A;//重载 B.printfushu(); A = A + B; A.printfushu(); system("pause"); return 0; }
例子2 #include<iostream> class sanwei { private: int x; int y; int z; public: sanwei(int a = 0,int b=0,int c=0) { x = a; y = b; z = c; } sanwei operator =(sanwei X) { this->x = X.x; this->y = X.y; this->z = X.z; return *this; } sanwei operator ++() { this->x++; this->y++; this->z++; return *this; } sanwei operator+(sanwei X) { sanwei temp; temp.x= this->x + X.x; temp.y = this->y + X.y; temp.z = this->z + X.z; return temp; } void show() { std::cout << "x=" << x << " " << "y=" << y << " " << "z=" << z << std::endl; } void assign(int a, int b, int c) { x = a; y = b; z = c; } }; void maiafadfaAn() { sanwei A(1,2,3); sanwei B; sanwei C; A.show(); B.show(); C.show(); B++; B++; B.show(); C = A + B; C.show(); C.assign(1, 2, 3); C.show(); system("pause"); } void mainkkk() { sanwei A(1,2,3); sanwei B; B = A; A.show(); B.show(); A = A + B; A.show(); A++; A.show(); system("pause"); }<span style="color:#57a64a;"> </span>
友元函数实现重载(友元函无this指针)
#include<iostream> class fushuA { friend fushuA operator -(fushuA & U, fushuA &V);//友元函数声明 private: int x, y; public: fushuA(int a=0, int b=0)//构造函数 { x = a; y = b; } fushuA operator+(fushuA a)//重载运算符 { fushuA temp(0, 0); temp.x = x + a.x; temp.y = y; return temp; } fushuA operator =(fushuA b);//=函数实现声明 void show() { std::cout << "x=" << x << " " << "y=" << y<< std::endl; } ~fushuA() { } fushuA operator ++()//前置 ++M调用这个 { this->x++; this->y++; return *this; } fushuA operator ++(int a)//后置 M++调用这个 { this->x++; x++; this->y++; return *this; } fushuA operator[] (fushuA *a) //[]实现重载 { std::cout << a->x << a->y << std::endl; return *this; } }; fushuA operator -(fushuA &U, fushuA &V)//友元函数实现运算符重载,因为友元函数木有this指针 { fushuA C; C.x = U.x - V.x; C.y = U.y - V.y; return C; } fushuA fushuA::operator =(fushuA b)//成员函数重载 移到外部 { x = b.x; y = b.y; return *this; } void main() { /*fushuA A(1, 9); fushuA B(3, 19); fushuA D; fushuA C; C = B+ A;//自己重载的运算符遵循自己的规则 // A.show(); C.show(); D = A+ B; D.show();//与c.show不同,不满足交换律是因为自己的规则 fushuA E = D - C; E.show();*/ fushuA M(10, 20); fushuA N; //N = M++;//指行的是 fushuA operator ++(int a) //N.show(); N = ++M;//执行的是 fushuA operator ++() N.show(); fushuA O(15, 25); O[&O];//[]实现重载 system("pause"); }
相关文章推荐
- C++中的初始化列表、const修饰的成员、友元类和友元函数、内联函数、static成员、构造函数的优化
- c++高级---C++类构造函数初始化列表以及对象成员的构造
- C++构造与析构(18) - 静态对象(static object)何时销毁
- C++构造与析构(18) - 静态对象(static object)何时销毁
- c++对象成员变量的构造和析构顺序
- C++不能中断构造函数来拒绝产生对象(在构造和析构中抛出异常)
- 一个有关C++中对象构造、析构和虚函数的问题
- C++对象的构造、赋值和析构
- static对象构造时成员变量的值
- C++的对象复制构造函数与赋值操作符重载的区别小结
- static对象和非static对象构造和析构顺序的问题
- 面向对象一(类、对象、变量、构造函数、构造代码块、this、static)
- C++在类之间调用static_cast转换时,需要复制构造函数
- 黑马程序员_Java基础_面向对象(概述、类与对象关系、成员变量、封装private、构造函数和构造代码块、this关键字)
- C++面向对象笔记:构造、析构函数、成员函数
- 从零开始学C++之对象的使用(一):static 成员变量、static 成员函数、类/对象的大小
- C++在类之间调用static_cast转换时,需要复制构造函数
- C++ 对象构造与析构以及内存布局
- 第05章 CORE C++_对象的创建和使用_继承_多态_析构_xxx_cast_友元_只读成员_静态成员_多重继承_虚继承_内部类
- C++对象构造时,构造函数运行时并不知道VT的存在