拷贝赋值函数
#include <string>
#include <iostream>
using namespace std;
class Person{
string name;
int age;
public:
Person(const string &name,int age):name(name),age(age){}
//拷贝构造和拷贝赋值函数
Person(const Person &p):name(p.name),age(p.age){}
Person& operator=(const Person &p)
{
cout <<"Hello,world."<<endl;
name = p.name;
age = p.age;
return *this;
}
};
int main()
{
Person P1("Jason Yu",26);
Person P2(P1); //拷贝构造生成
Person P3=P2;//拷贝构造生成
P1=P3;//拷贝赋值生成
return 0;
}
这里在极客时间上刷到每日一课里面的一个小教程,视频链接什么是C++中的The Rule of Three?
最开始我以为Person P3=P2;是调用的拷贝赋值函数,因为看到了=号。
验证方法是在拷贝赋值函数中添加打印,然后编译运行,输出打印内容,注释掉P1=P3之后,编译运行,打印内容消失,由此可以证明P1=P3才调用的拷贝赋值函数。
详细解释:
需要注意的是变量在初始化时是不会调用“copy-assignment operator”的,相反这里调用的是“copy-constructor”。因为这里我们是在声明“P3”的时候就直接进行初始化了“Person P3 = P2;”。为了更加明确,如果后面还有一行代码是“P1 = P3;”,那这里由于“P1”已经经过初始化所以就会调用拷贝赋值函数/运算符。
delete
#include <bits/stdc++.h>
using namespace std;
struct P {
static void operator delete(void* ptr, std::size_t sz)
{
cout << "custom delete for size " << sz <<endl;
delete (ptr); // ::operator delete(ptr) can also be used
}
static void operator delete[](void* ptr, std::size_t sz)
{
cout << "custom delete for size " << sz <<endl;
delete (ptr); // ::operator delete(ptr) can also be used
}
};
int main()
{
P* var1 = new P;
delete var1;
P* var2 = new P[10];
delete[] var2;
}
如下代码输出什么,并解释为什么?
输出结果:
custom delete for size 1
custom delete for size 18
解释:
应该是编译器在new分配数组内存的时候,前面多分配了一个整数大小的空间用来存储数组长度,不然delete []操作不能确定数组大小。这个大小和机器有关,你应该是在64位机器上验证的,所以这个长度用64位存储,即8字节。struct没有成员,空间占用为0,但是编译器会给它分配1字节的空间。结果就是8+10*1。当然,这个行为标准并没有定义,所以还是实现相关的,只不过大部分都是这样实现的。
例子来源operator,针对示例代码,下面有提示可能的输出.
空结构体sizeof为1
上面的解释中提到了一点,struct没有成员,sizeof执行为1,这是因为什么呢?
C++作者给出了解释FAQ
To ensure that the addresses of two different objects will be different. For the same reason, "new" always returns pointers to distinct objects.
示例程序:
#include <iostream>
class Empty{};
struct X:Empty
{
int a;
};
void empty()
{
Empty a, b;
if (&a == &b) std::cout << "impossible: report error to compiler supplier";
Empty* p1 = new Empty;
Empty* p2 = new Empty;
if (p1 == p2) std::cout << "impossible: report error to compiler supplier";
}
void optimizer(X *p)
{
void * p1=p;
void * p2 = &p->a;
if(p1 == p2)
std::cout <<"nice : good optimizer"<<std::endl;
}
int main()
{
empty();
X a;
optimizer(&a);
return 0;
}
翻译成中文:
空类大小为1的原因是:
为了确保两个不同对象的地址不同,必须如此。也正因为如此,new返回的指针总是指向不同的单个对象。
空基类并不需要另外一个字节表示,原因是:它允许程序员用空类来表示非常简单的概念,而不需为此付出额外的(空间)代价。一些现代编译器提供了这种“虚基类优化”功能。
详细的空基类优化:
libcurl -multi接口学习
工作中需要优化一个使用libcurl-multi的吞吐量,使得每秒请求的量double。使用到的几篇非常不错的文章:
How to do curl_multi_perform() asynchronously in C++?
C++中default和delete函数
上面文章中清单9代码存在错误,正确的代码如下:
#include <iostream>
class X {
public:
virtual ~X()= default; // 编译器自动生成 defaulted 函数定义体
private:
int x;
};
class Y: public X {
public:
~Y()
{
std::cout<<" Hello,world."<<std::endl;
}
private:
int y;
};
int main()
{
X* x = new Y;
delete x;
return 0;
}
进程相关
在朋友圈看到一篇非常不错的文章,虽然很基础,实例和测验恰到好处,这个网站上也有一些其它教程。
explicit关键字作用
gtest linux安装方法