函数重载
函数参数个数,类型,顺序不同
实现原理
编译器会修改函数名,带上参数类型
extern C
在C++中想调用C语言方法
// Cpp
#include <iostream>
// 在C++中想调用C语言方法
extern "C" {
#include "test.h"
}
int main()
{
show(); // 在C++中函数可以重载,编译器会把函数名偷偷修改了
std::cout << "Hello World!\n";
}
// .c
#include "test.h"
void show() {
printf("sfs");
}
// .h
#pragma once
#include<stdio.h>
void show();
// .h
#pragma once
// 如果这是一段cpp的代码,那么加入extern "C"{和}处理其中的代码。
#ifdef __cplusplus
extern "C" {
#endif
#include<stdio.h>
void show();
#ifdef __cplusplus
}
#endif // !__cplusplus
C++与C封装的区别
C 中封装,属性与行为分开处理了,且类型转换检测不够
struct class 默认权限不同
构造,拷贝
- 当我们自己写了拷贝构造,系统不会在提供其他构造
- 当我们自己写了有参构造,系统不会提供默认构造,但是会提供默认拷贝
// 普通构造
Person(int age) : age(age) {
}
Person p1(100);
Person p1 = Person(100);
Person(10); // 匿名对象
// 拷贝构造
// 拷贝构造调用时机
// 用以创建的对象构造新对象
// 以值传递的方式给函数参数传值,调用拷贝
// 以值方式返回局部遍历,调用拷贝
// release 模式下会优化
Person(const Person& p) {
}
Person p1(p2);
Person p1 = p2;
Person p; // 调用默认构造函数
Person p1(); // 编译器认为是函数声明
// 显示法调用
Person p4 = Person(100); // 调用有参
Person P5 = Person(p4); // 调用拷贝构造
// 匿名对象,这段代码结束后就释放对象
Person p6;
// 错误,编译器认为是 Person p5;(声明) p5被重定义,拷贝构造必须做右值
// Person(p5);
深拷贝,浅拷贝
浅拷贝
拷贝构造函数是系统默认拷贝,简单的值拷贝(拷贝了地址而已)
name会因为释放2次而出错
int age;
char* name;
Person(int age, char *_name) : age(age) {
std::cout << "putong" << std::endl;
name = (char*)malloc(strlen(_name) + 1);
strcpy(name, _name);
}
深拷贝,(重写拷贝构造)
自行给指针分配空间,
// 拷贝构造
Person(const Person& p) {
std::cout << "kaobei" << std::endl;
age = p.age;
name = (char*)malloc(strlen(p.name) + 1);
strcpy(name, p.name);
}

类对象作为类的成员
构造顺序:先将类对象以此狗仔
class Phone {
string name;
public:
Phone(string name): name(name) {};
~Phone() {};
};
class Game {
public:
Game() {};
~Game() {};
};
class Person
{
int age;
char* name;
string address;
Phone p;
Game game;
public :
// 必须要有Phone(string name): name(name) {};构造才行
Person(string phoneName) : p(phoneName) {
}
}
explicit
防止隐式类型转换
#pragma once
class MyString
{
public:
MyString(const char* str) {
}
MyString(int a) {
}
// explicit MyString(int a) {
//
// }
char* str;
};
void test01() {
// MyString(const char* str)有参构造
MyString str = "abs";
// MyString(int a) 有参构造
MyString str2(10);
// 隐式类型转换
// MyString str3 = MyString(100);
// explicit加上后,这句报错了。
// explicit:防止隐式类型转换
MyString str3 = 100;
}
new 动态对象创建
malloc
- 必须确认对象长度
malloc(strlen(strings) + 1);
malloc(sizeOf(Person));
- malloc返回void * 指针,所以必须强转后才能使用。
Person *p =(Person *)malloc(sizeOf(Person));
- malloc分配内存可能会失败。所以必须判断返回值确认是否分配成功
if(p == NULL) {
return 0;
}
- 使用对象前必须进行初始化
new delete
运算符
在堆区开辟空间,所有new出来的对象,都会返回该类型的指针
Person *person = new Person;
delete person;
Person *persons = new Person[10]; // 一定调用默认构造
delete[] persons;
本文详细探讨了C++中的关键概念,包括函数重载的实现原理,如何在C++中使用`extern C`调用C语言方法,C++与C封装的区别,构造函数与拷贝构造函数的使用细节,明确使用`explicit`关键字的作用,以及`new`和`delete`操作符在动态对象创建和内存管理中的应用。此外,还讨论了深拷贝与浅拷贝的概念,并强调了正确使用`new`避免内存错误的重要性。

3329

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



