参数传递
//
// Created by glt on 2025/3/16.
//
//
// Created by glt on 2025/3/16.
//
#include <iostream>
#include "Person.h"
void method1(Person p){
std::cout<<"method1 address::"<<&p<<std::endl;
std::cout<< p.get_name()<<std::endl;
}
void method2(Person& p){
std::cout<<"method2 address::"<<&p<<std::endl;
p.name= "meth2";
}
void method3(Person* p){
std::cout<<"method3 address::"<<p<<std::endl;
p = new Person("innner");
}
void method4(Person*& p){
std::cout<<"method4 address::"<<p<<std::endl;
p = new Person("innner");
}
int main(){
Person p1("zhangsan");
std::cout<<"p1 address::"<<&p1<<std::endl;
//p1.sayHello();
method1(p1);
method2(p1);
method3(&p1);
method4(reinterpret_cast<Person *&>(p1));
auto* p2 = new Person("lisi");
std::cout<<"p2 address::"<<p2<<std::endl;
method1(*p2);
method2(*p2);
std::cout<< "after method2 p2 name:"<< p2->get_name()<<std::endl;
method3(p2);
std::cout<< "after method3 p2 name:"<< p2->get_name()<<std::endl;
method4(p2);
std::cout<< "after method4 p2 name:"<< p2->get_name()<<std::endl;
}
看看上面的代码,输出如下:
C:\my_program\CLionProjects\toy\cmake-build-debug\AboutPara.exe
p1 address::0x5ffc90
method1 address::0x5ffcf0
zhangsan
method2 address::0x5ffc90
method3 address::0x5ffc90
method4 address::0x5ffca0
p2 address::0x1b48f0
method1 address::0x5ffd50
lisi
method2 address::0x1b48f0
after method2 p2 name:meth2
method3 address::0x1b48f0
after method3 p2 name:meth2
method4 address::0x1b48f0
after method4 p2 name:innner
Process finished with exit code 0
上面的代码说明了
- 1 直接使用method1这种方式,会把对象复制一份比较浪费性能。
- 2 method3 method2 可以改变外面参数的值
- 3 method4 才能改变外面指针的指向
说说const
有一个person类
const person p1;
p1的成员变量的值都不能变。
里面的name,age都不能变。
假如person里面还有一个Address* myadd的变量。
因为p1被加了const,所以里面的address的变量不能再指向别的地方
即 p1->myadd = new Address()是错误的
但是可以 修改myadd里面具体的值
即p1->myadd->city = 10;
因为const只限制了person域不能修改,拿到person内myadd的地址之后的操作 const就管不上了。
const person* p2 = new person();
p2的成员变量的值都不能变。
但是p2可以指向一个新的对象
// 声明并初始化一个指向常量Person对象的常量指针
const Person* const p22 = new Person();
上面p22 成员变量的值不能修改 而且p22 也不能志向一个新的person地址
const std::vector<Person> p3;
p3的大小不能变。
也不能修改里面任意一个对象的成员变量
const std::vector<Person*> p4;
p4的大小不能变。
p4[2] = new person(); 不行
p4[2]->age = 10 ; 可以
关于 引用与指针的初始化与使用
int k = 4158;
int k2 = 12;
int &p = k;
const int &m = 1234;
//int &m = 123; //引用的初始值必须是对象
p = k2;
&p = k2; //不行
&p = 123; //不行
int k = 12;
int s = 333;
int *m = &k;
int *h = 1234;//不行
int *h2 = k;//不行
int p = 11;
*m = p;
m = &s;
m = s;//不行
m = 123;//不行
引用与指针的一个说明
假定有个person类,里面有name和age,有个print方法会打印出name和age
int main() {
auto* p1 = new Person("dlf",21);
Person& p2 =*p1;
p1->print();
p2.print();
std::cout<<"point address:"<< &p1<< " true obj add:" << p1<< " true obj add:"<< &p2<<std::endl;
auto* p3 = new Person("zs",22);
p2 = *p3;
p1->print();
p2.print();
std::cout<<"point address:"<< &p1<< " true obj add:" << p1<< " true obj add:"<< &p2<<std::endl;
Person p4("ls",35);
p2 = p4;
p1->print();
p2.print();
std::cout<<"point address:"<< &p1<< " true obj add:" << p1<< " true obj add:"<< &p2<<std::endl;
}
如上的代码,运行一次大家就能看到引用的意思了
Person& p2 =*p1;
至此以后,p2就是p1,p1就是p2。他们标明同一块内存。
参数传递的变与不变
上面我们说了如果使用一个指针作为函数的参数,那么内部的修改会影响外部
Person里面有个方法叫add,参数是Person *p,那么对p的所有修改,会影响真实的外部调用 这叫使用指针做函数参数
说白了就是上面这句话。
void serialize(char *ptr) const {
ptr += sizeof(int);
}
char *myptr = static_cast<char *>(buffer);
for (const auto &p: people) {
printf("Pointer address1 : %p\n", (void *)myptr);
p.serialize(myptr);
printf("Pointer address2 : %p\n", (void *)myptr);
}
在一次循环中,address1 和 address2 会一样么?
答案是一样。
假如在方法里修改了ptr的内容,那么是会影响到外面的myptr。
但是你在方法内部修改ptr的指向,那原来myptr的位置 依然没有变呀。
拷贝构造函数
还是上面的代码
//
// Created by glt on 2025/3/16.
//
#include <iostream>
#include <vector>
#include <unordered_map>
#include "Person.h"
void method1(Person p){
std::cout<<"method1 address::"<<&p<<std::endl;
std::cout<< p.get_name()<<std::endl;
}
void method2(Person& p){
std::cout<<"method2 address::"<<&p<<std::endl;
p.name= "method2";
}
void method3(Person* p){
std::cout<<"method3 address::"<<p<<std::endl;
p = new Person("innner");
}
void method4(Person*& p){
std::cout<<"before method4 address::"<<p<<std::endl;
p = new Person("innner");
std::cout<<"after method4 address::"<<p<<std::endl;
}
int main(){
Person p1("zhangsan");
std::cout<<"p1 address::"<<&p1<<std::endl;
method1(p1);
method2(p1);
method3(&p1);
Person p2(p1);
p2.name="new p2";
std::cout<<"change name"<<std::endl;
Person p3 = p2;
p3.name="new p3";
std::vector<Person> myvector;
std::cout<<"before init vector"<<std::endl;
myvector.push_back(p3);
std::cout<<"after init vector"<<std::endl;
Person p4 = p3;
p4.name="new p4";
std::unordered_map<std::string ,Person> my_map;
std::cout<<"init map"<<std::endl;
my_map["p1"]=p4;
}
C:\my_program\CLionProjects\toy\cmake-build-debug\AboutPara.exe
p1 address::0x966c5ff680
copy construct zhangsan
method1 address::0x966c5ff6e0
zhangsan
method2 address::0x966c5ff680
method3 address::0x966c5ff680
copy construct method2
change name
copy construct new p2
before init vector
copy construct new p3
after init vector
copy construct new p3
init map
Process finished with exit code 0
上面的代码说明 对于一个对象Person p1;
- method1(p1);
- Person p2(p1);
- Person p3 = p1;
- std::vector myvector;
myvector.push_back(p1);
大家要注意:上面这4种情况都会调用拷贝构造函数,数据都被被复制一遍!

被折叠的 条评论
为什么被折叠?



