1,请问类中函数 const修饰的谁?
[email protected]:~/c++$ cat main.cpp #include <iostream> #include <stdlib.h> using namespace std; class A { public: //const的三种写法 //const void fun(int a,int b) //void const fun(int a,int b) //void fun(int a,int b) const void fun(int a,int b) const { a = 100; //const 修饰的不是a //this->a = 200; //编译提示:‘A::a’ in read-only object } private: int a; int b; }; int main() { A a1; return 0; }
答案:
const的三种写法修饰的是this指针
const void fun(int a,int b)
void const fun(int a,int b)
void fun(int a,int b) const
this指针所指向的内存空间不能被修改
相当于 void fun(const A *this,int a,int b)
修改this指针本身的值,编译也不通过
把类中的成员函数 转换成全局函数
[email protected]:~/c++$ cat main.cpp #include <iostream> #include <stdlib.h> using namespace std; class A { public: void fun() { cout << "a="<<this->a<<" b="<<this->b<< " in fun"<<endl; } A(int a=0,int b=0) { this->a = a; this->b = b; cout << "a="<<this->a<<" b="<<this->b<<" in init \n"; } A add(A &a) { A t(this->a + a.a,this->b + a.b); return t; } A (const A &obj) { cout << "in copy \n"; } ~A() { cout << "a= "<<a << " b="<<b <<" free\n"; } public: int a; int b; }; //把成员函数转成全局函数 A fun(A &a1,A &a2) { A a3; return a3; } void fun1() { cout << "-------- in fun1 ------------------- \n"; A a1(1,2); A a2(3,4); A a3 = a1.add(a2); a3.fun(); } void fun2() { cout << "-------- in fun2 ------------------- \n"; A a1(1,2); A a2(3,4); A a3(5,5); a3 = a1.add(a2); a3.fun(); } int main() { fun1(); fun2(); return 0; } [email protected]:~/c++$ g++ -g main.cpp && ./a.out -------- in fun1 ------------------- a=1 b=2 in init a=3 b=4 in init a=4 b=6 in init a=4 b=6 in fun a= 4 b=6 free a= 3 b=4 free a= 1 b=2 free -------- in fun2 ------------------- a=1 b=2 in init a=3 b=4 in init a=5 b=5 in init a=4 b=6 in init a= 4 b=6 free a=4 b=6 in fun a= 4 b=6 free a= 3 b=4 free a= 1 b=2 free
成员函数返回*this
[email protected]:~/c++$ cat main.cpp #include <iostream> #include <stdlib.h> using namespace std; class A { public: void fun() { cout << "a="<<this->a<<" b="<<this->b<< " in print"<<endl; } A(int a=0,int b=0) { this->a = a; this->b = b; cout << "a="<<this->a<<" b="<<this->b<<" in init \n"; } //返回一个引用,相当于返回自身 A& add(A &a) { this->a += a.a, this->b += a.b; return *this; } A (const A &obj) { cout << "in copy \n"; } ~A() { cout << "a="<<a << " b="<<b <<" free\n"; } public: int a; int b; }; int main() { A a1(1,2); A a2(3,4); a1.add(a2); a1.fun(); return 0; } [email protected]:~/c++$ g++ -g main.cpp && ./a.out a=1 b=2 in init a=3 b=4 in init a=4 b=6 in print a=3 b=4 free a=4 b=6 free [email protected]:~/c++$
自定义数组类封装 具有以下函数
void arr_set(int n,int value);
int arr_get(int n);
int arr_len();
文件1:
[email protected]:~/c++$ cat my_arr.h #pragma once class Arr { public: void arr_set(int n,int value); int arr_get(int n); int arr_len(); Arr(int n); Arr(const Arr &boj); ~Arr(); private: int len; int *arr; }; [email protected]:~/c++$
文件2:
[email protected]:~/c++$ cat my_arr.cpp #include "my_arr.h" #include <iostream> using namespace std; void Arr::arr_set(int n,int value) { this->arr[n] = value; } int Arr::arr_get(int n) { return this->arr[n]; } int Arr::arr_len() { return this->len; } Arr::Arr(int n) { if(n<1) { len = 0; arr = NULL; } else { this->len = n; arr = new int [n]; cout << n <<" init ...\n"; } } Arr::Arr(const Arr &obj) { this->len = obj.len; arr = new int [this->len]; for(int i = 0;i<this->len;i++) { this->arr[i] = obj.arr[i] + 1; } cout << this->len<<" copy ...\n"; } Arr::~Arr() { if(arr != NULL) { cout << this->len<<" free ...\n"; delete [] arr; len = 0; } } [email protected]:~/c++$
文件3:
[email protected]:~/c++$ cat main.cpp #include <iostream> #include "my_arr.h" #include <stdlib.h> using namespace std; int main() { Arr a1(20); for(int i = 0;i<a1.arr_len();i++) { a1.arr_set(i,i); } for(int i = 0;i<a1.arr_len();i++) { cout << a1.arr_get(i) << " "; } cout << endl; Arr a2 = a1; //等号操作,C++编译器会调用拷贝构造函数 for(int i = 0;i<a2.arr_len();i++) { cout << a2.arr_get(i) << " "; } cout << endl; return 0; }
编译运行:
[email protected]:~/c++$ g++ -g main.cpp my_arr.cpp && ./a.out 20 init ... 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 copy ... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 20 free ... 20 free ... [email protected]:~/c++$
为什么会有友元函数?
在实现类之间数据共享时,减少系统开销,提高效率。
如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。
具体来说:为了使其他类的成员函数直接访问该类的私有变量。
即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。
实际上具体大概有下面两种情况需要使用友元函数:
(1)运算符重载的某些场合需要使用友元。
(2)两个类要共享数据的时候。
[email protected]:~/c++$ cat main.cpp #include <iostream> #include <stdlib.h> using namespace std; class A { public: A(int a,int b) { this->a = a; this->b = b; } private: int a; int b; }; void fun(A *p) { //不能在类的外部访问私有属性 int n =p->a; } int main() { A a1(1,2); fun(&a1); return 0; } 编译就报错: [email protected]:~/c++$ g++ -g main.cpp && ./a.out main.cpp: In function ‘void fun(A*)’: main.cpp:13:6: error: ‘int A::a’ is private int a; ^
把这个函数添加为友元函数就OK了
友元函数 与 位置没有关系
[email protected]:~/c++$ cat main.cpp #include <iostream> #include <stdlib.h> using namespace std; class A { friend void fun(A *p); public: A(int a,int b) { this->a = a; this->b = b; } int get_a() { return this->a; } private: int a; int b; }; void fun(A *p) { //不能在类的外部访问私有属性 p->a = 10; int n =p->a; cout << n << endl; } int main() { A a1(1,2); fun(&a1); cout << a1.get_a() << endl; return 0; } [email protected]:~/c++$ g++ -g main.cpp && ./a.out 10 10
友元类:
[email protected]:~/c++$ cat main.cpp #include <iostream> #include <stdlib.h> using namespace std; class A { friend class B; private: int a; }; class B { friend void fun(A *p); public: B(int a) { a1.a = a; //可以直接修改友元类的属性 } int get_a() { return this->a1.a;////可以直接修改友元类的属性 } private: int a; A a1; }; int main() { B b1(11); cout << b1.get_a() << "\n"; return 0; } [email protected]:~/c++$ g++ -g main.cpp && ./a.out 11 [email protected]:~/c++$
运算符重载,初步
让两个类直接相加减
运算符重载本质是一个函数
约定operator关键字
C++编译器会自动去找运算符
[email protected]:~/c++$ cat main.cpp #include <iostream> #include <stdlib.h> using namespace std; class A { public: A(int a,int b) { this->a = a; this->b = b; } int printf() { cout <<a<<" "<<b<<endl; } int a; int b; }; A operator+(A &a,A &b) { cout << "Hello World \n"; A t(a.a+b.a,a.b+b.b); return t; } int main() { A a1(1,1); A a2(2,2); A a3 = a1+a2; a3.printf(); return 0; } [email protected]:~/c++$ g++ -g main.cpp && ./a.out Hello World 3 3 [email protected]:~/c++$
可以进行运算符重载的符合
不可以进行运算符重载的符合
时间: 2024-10-19 05:22:51