1.关于xxx.h.gch
编译的时候切记不要把头文件编译进去,生成的xxx.h.gch文件是一种缓存,其后编译文件时调用头文件便一直是该缓存。
2.关于inline函数的重定义问题
inline.h
1 #pragma once
2
3 inline int add(int a,int b)//如果这里不使用内联函数,将导致重定义问题
4 {
5 return a+b;
6 }
inline.cc
1 #include "inline.h"
testInline.cc
1 #include "inline.h"
2 #include <iostream>
3 using std::cout;
4 using std::endl;
5
6 inline int add(int,int);
7 int main()
8 {
9 cout<<add(3,4)<<endl;
10 return 0;
11 }
3.C++定义的变量所在的内存区
内存区的划分:数据区,代码区,BSS区,堆,栈
#include <stdio.h>
#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
int a = 1;//全局静态区
char * p1;//全局变量如果没有显式进行初始化,系统也会设置默认值
int test0(void)
{
int b = 2;
const char * p2 = "hello,world";//文字常量区
char str[] = "hello,world";//栈区
//str = 0x1000;//str 常量
char * p3;//野指针
p3 = new char[20]();//堆区
strcpy(p3, "hello,world");//与以上p2所指的"hello,world"为同一个
static int c = 100;//局部静态变量, 全局/静态区
++c;
printf("sizeof(str) = %lu\n", sizeof(str));
printf("sizeof(p2) = %lu\n", strlen(p2));
printf("&a = %p\n", &a);
printf("&b = %p\n", &b);
printf("p1 = %p\n", p1);
printf("&p1 = %p\n", &p1);
printf("p2 = %p\n", p2);
printf("&p2 = %p\n", &p2);
printf("str = %p\n", str);
printf("p3 = %p\n", p3);
//*p3 = '1';//error 野指针
printf("&p3 = %p\n", &p3);
printf("&c = %p\n", &c);
printf("address(hello,world) = %p\n", "hello,world");
printf("address(test0) = %p\n", &test0);//程序代码区
return 0;
}
int main(void)
{
test0();
return 0;
}
4.防止在析构函数中delete多次
#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
class Computer
{
public:
Computer(const char * brand, double price)
: _brand(new char[strlen(brand) + 1]()) //浅拷贝, 只传地址
, _price(price)
{
strcpy(_brand, brand);
cout << "Computer(const char *, double)" << endl;
}
void print()
{
cout << " brand:" << _brand << endl
<< " price:" << _price << endl;
}
//对象销毁的过程中会自动调用析构函数
#if 0
void release()
{
delete [] _brand;
}
#endif
~Computer()
{ //析构函数的作用:是用来回收对象申请的资源
if(_brand) {//防止delete多次
delete [] _brand;
_brand = nullptr;//NULL
}
cout << "~Computer()" << endl;
}
private:
char * _brand;
double _price;
};
//Computer pc2("Xiaomi", 7500);
int test0(void)
{
{
Computer pc1("MateBook", 6666);
cout << ">> pc1: " << endl;
pc1.print();
}
cout << ">> pc2: " << endl;
// pc2.print();
//堆空间的对象的销毁,需要手动执行
Computer * pc3 = new Computer("Thinkpad", 7777);
cout << ">> pc3: " << endl;
pc3->print();
delete pc3;//不要忘了, 执行delete表达式的过程中,就会调用析构函数
static Computer pc4("Macbook pro", 20000);
cout << ">> pc4: " << endl;
pc4.print();
return 0;
}
void test1()
{
Computer * pc3 = new Computer("Thinkpad", 7777);
cout << ">> pc3: " << endl;
pc3->print();
pc3->~Computer();//该语句被执行之后,对象是没有被销毁的
//这里手动销毁调用delete,执行完毕自动调用时调用delete,故delete了两次
//所以要采用如上析构函数的写法
delete pc3;
}
void test2()
{
Computer pc1("MateBook", 6666);
cout << ">> pc1: " << endl;
pc1.print();
pc1.~Computer();//析构函数可以主动调用,但不推荐这样做
//析构函数应该让其自动执行
//pc1.release();
}
int main(void)
{
//test1();
test2();
return 0;
}
在堆空间,栈空间,静态区,全局区都可以自动调用析构函数,但是在堆空间只有delete时会调用堆空间。
本文总结了C++编程中的一些常见细节问题,包括头文件的编译生成的.gch缓存,inline函数的重定义,内存区域划分,以及如何避免在析构函数中对同一对象多次delete,提供了理解和解决这些问题的要点。
&spm=1001.2101.3001.5002&articleId=92800893&d=1&t=3&u=5be618d39837406d9606efcabc087b52)
1967

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



