目录
1.命名冲突,
c++引入了namespace来解决这个问题,c语言没有
c++如下
namespace xxx {
int x = 0;
}
namespace 默认以局部变量优先(全局和局部变量比较)
加个 ::以全局变量优先,如 ::x
#include <stdio.h>
#include <stdlib.h>
namespace me {
int rand = 0;
}
int a = 0;
int main() {
int a = 1;
printf("%p\n", rand);
printf("%d\n", rand);
printf("%d\n", a);
printf("%d\n", ::a); //Domain-scoped qualifier 域作用限定符
}
那么如果我们要访问me这个域里面的变量呢?(int rand = 0 这个变量)
再::前面加个me就可以了, 这也从侧面显现了namespace 的命名很重要。
举个例子,大家一起写一份文件的时候难免会遇到变量重复的情况,这时候只要在把重复的变量放在个人专属的namespace中就可以避免重复而导致编译不过的问题。c++的优势。
#include <stdio.h>
#include <stdlib.h>
namespace me {
namespace Ding {
int rand = 0;
}
namespace JJ {
int rand = 0;
}
}
int a = 0;
int main() {
int a = 1;
printf("%d\n", rand);
printf("%d\n", me::Ding::rand);
printf("%d\n", a);
printf("%d\n", ::a); //Domain-scoped qualifier 域作用限定符
}
命名空间也是能嵌套的
最后一点,如果不小心用了两个相同的命名空间,那么编译器会怎么办呢?
答:编译器不会报错,因为同一个工程允许存在相同的命名空间,编译器会把相同的命名空间合并到一起,形成一个新的命名空间
2.using namespace std
展开命名空间,可以做到少些几个子,但这是在没有变量相同的情况下才能这么做,不然还得老老实实写命名空间
#include <stdio.h>
#include <stdlib.h>
namespace me {
int a = 2;
namespace Ding {
int rand = 0;
}
namespace JJ {
int rand = 0;
}
}
using namespace me;//展开命名空间会使变量重复,就比如你的rand
int a = 0;
int main() {
int a = 1;
printf("%d\n", rand);
printf("%d\n", Ding::rand);
printf("%d\n", a);
printf("%d\n", me::a); //Domain-scoped qualifier 域作用限定符
printf("%d\n", a);
}
如果把me::a的me::去掉的话,编译器会把a默认是局部变量(因为main函数内刚好有个局部变量----优先级最高)
所以 我们常看到 using namespace std;
这里的std实际上就是c++库的命名空间,
就像这句话
cout << "hello world" << endl;
如果不加using namespace std,这句话是无法通过编译的,要这么写
std::cout << "hello world" << std::endl;
当然你加了std的命名空间也能这么写,但是不推荐
或者你加那么std::cout 直接就能编译
这里有种骚操作
#include <iostream>
//using namespace std; 这里不放出来
int cout = 0;
int main() {
std::cout << cout << std::endl;
return 0;
}
这就是命名空间的优势。C++!
3.C++函数参数默认值设置
C++支持在声明并且定义的函数内对参数赋值,或者在声明的函数内赋值(定义的函数内不赋值)
,这样你在运用函数的时候不传参,编译器会自动使用对参数赋值的那个值
void function(int a = 1) {
cout << a << endl;
}
int main() {
function();
function(2);
return 0;
}
4.C++支持重载
话不多说,上图:
#include <iostream>
using namespace std;
int add(int x, int y) {
return x + y;
}
double add(double x, double y) {
return x + y;
}
int main() {
cout << add(1, 2) << endl;
cout << add(1.1, 2.1) << endl;
}
当然,C++不支持函数相同,参数不同的情况
参数不同:参数类型不同,参数顺序不同,参数个数不同
5.Struct 和 Class的区别
struct 默认为public
class 默认为private
class 比 struct 更加安全,不会被别人随意调用成员变量进行修改
class private 定义的成员变量可以在 public 定义的成员函数中提取 (当然这需要我们自己实现)。
class 除了 private 和 public 还有 protect,除了在继承方面和private 有区别,其余和private 基本一致。
6.权限问题
权限不可以放大
权限只能缩小使用
非 const 对象 可以调用 const成员函数
const 对象 不可以调用 非 const成员函数
const 成员函数内不能调用其他的 非 const 成员函数
非 const 成员函数内可以调用其他的 const 成员函数
日后更新。
7.指针和malloc
对于c++而言, NULL其实就是0,但也可以用作空指针 ((void *) 0)
在函数重载的时候会有bug, 系统无法分辨出这个是要用作void *p 还是 int i, 因此编译器会报错
而同样的 malloc 返回值C++默认是 void *, 如果不强制转换类型的话, 也会报错
#include <iostream>
using namespace std;
void test(void *p) {
cout << p << endl;
}
void test(int i) {
cout << i << endl;
}
int main() {
test(NULL);
int *p = malloc(100 * sizeof(int));
}
所以C++引入了 nullptr 来避免 函数重载问题,nullptr 剥离了NULL 为0的定义,只保留空指针的意思
而对于malloc,应该使用强转解决
8.初始化列表
初始化列表是为了对 const,别名 这些变量在定义的时候就初始化
初始化列表 可以不用在函数()申明参数,直接调用成员变量
初始化列表可以认为就是对象的成员变量定义的地方
对于内置自定义成员变量,也应该用初始化列表进行赋值,或者使用默认构造
每个成员变量在初始化列表只能定义一次
成员变量声明顺序才是 初始化列表初始化顺序