命名空间
1、命名空间的定义
使用namespace
定义,使用作用域限定符::
访问
c++
#include <iostream>
namespace ICBC{
int money = 0;
void save( int m){
money += m;
}
}
int main( void ){
ICBC::save( 100);
std::cout << "工行卡余额:" << ICBC::money << std::endl;
return 0;
}
2、声明定义分开
c++
#include <iostream>
namespace BOC{
int money = 0;
void save( int m){ // 声明同时定义
money += m;
}
void pay( int m); // 声明
}
void BOC::pay( int m){ // 定义
money -= m;
}
int main( void ){
BOC::save( 100);
BOC::pay( 50);
std::cout << "中国银行余额:" << BOC::money << std::endl;
return 0;
}
3、命名空间的自动合并
多个文件或位置的相同namespace会被编译器自动合并。
c++
#include <iostream>
namespace ICBC{
int money = 0;
void save( int m){
money += m;
}
}
namespace BOC{
int money = 0;
void save( int m){ // 声明同时定义
money += m;
}
void pay( int m); // 声明
}
namespace ICBC{
void pay( int m){
money -= m;
}
}
void BOC::pay( int m){ // 定义
money -= m;
}
int main( void ){
ICBC::save( 100);
ICBC::pay( 50);
std::cout << "工行余额:" << ICBC::money << std::endl;
BOC::save( 1000);
BOC::pay( 500);
std::cout << "中国银行余额:" << BOC::money << std::endl;
return 0;
}
3、命名空间指令
C++中有 定义表和可见表。
using namespace std
为名字空间指令,表示从这行代码开始,std中的内容在当前作用域可见,在可见表
c++
// 命名空间指令
#include <iostream>
using namespace std;
namespace ns{
int g_value = 0;
}
//int g_value = 0;
//using namespace ns; // 命名空间指令:从这行代码开始,ns中的内容在当前作用域可见
int main( void ){
// int g_value = 0;
using namespace ns; // 命名空间指令:从这行代码开始,ns中的内容在当前作用域可见
g_value = 666; //
/*std::*/cout << "ns::g_value = " << ns::g_value << /*std::*/endl;
return 0;
}
4、命名空间声明
命名空间声明会让其出现在定义表中
c++
// 命名空间声明
#include <iostream>
using namespace std;
namespace ns{
int g_value = 0;
}
//int g_value = 0;
//using ns::g_value; // 从这行代码开始,ns中的g_value引入当前作用域(相当于定义)
int main( void ){
// int g_value = 0;
using ns::g_value; // 从这行代码开始,ns中的g_value引入当前作用域(相当于定义)
g_value = 666; //
cout << "ns::g_value = " << ns::g_value << endl;
return 0;
}
5、命名空间嵌套和别名
命名空间嵌套
- 内层标识符与外层同名标识符为隐藏关系
- 嵌套的命名空间需要逐层分解
命名空间别名
- 可通过命名空间别名简化书写
namespace ns four = ns1::ns2::ns3::ns4;
c++
#include <iostream>
using namespace std;
namespace ns1{
int g_value = 100;
namespace ns2{
int g_value = 200;
namespace ns3{
int g_value = 300;
namespace ns4{
int g_value = 400;
}
}
}
}
int main( void ){
namespace ns_four = ns1::ns2::ns3::ns4; // 别名
cout << ns_four::g_value << endl;
return 0;
}
C++的复合类型
- C++的结构体
- 结构体内部可以定义成员函数
- 在成员函数的内部可以直接访问本结构体的成员,无需通过
.
或->
- C++的联合
- 支持匿名联合
- C++的枚举
- 独立的类型,和整型数据之间不能隐式转换
- 表示布尔量的数据类型
- bool
- 布尔类型的字面值常量
- true 表示真
- false 表示假
- 布尔类型的本质
- 单字节整数,用1和0表示真和假
- 任何基本类型的数据都可以被隐式转换为布尔类型
- 非0即真,0即假
c++
// C++的复合类型
#include <iostream>
#include <cstring>
using namespace std;
void TestStruct(){
struct Student{
int m_age; // 成员变量
char m_name[256]; // 成员变量
void getInfo(){ // 成员函数
cout << "getInfo(): 姓名:" << m_name << ", 年龄:" << m_age << endl;
}
};
/*struct*/ Student s;
s.m_age = 22;
strcpy(s.m_name,"张三");
cout << "姓名:" << s.m_name << ", 年龄:" << s.m_age << endl;
s.getInfo();
}
void TestUnion(){
union{ // 匿名联合,主要想体现所有的成员共用同一块内存空间
int i;
char c[4];
};
i = 0x12345678; // 小端字节序
cout << hex << (int)c[0] << ' ' << (int)c[1] << ' ' << (int)c[2] << ' ' << (int)c[3] << endl;
}
void TestEnum(){
enum Color{red, green, blue};
/*enum*/ Color c = red; // 0;error
std::cout << c << std::endl;
}
void TestBool(){
bool a = "Hello"; // 0.0000001; // 123; // true;
bool b = NULL; // 0.0000000; // 0; // false;
cout << "a=" << a << ", b=" << b << endl;
}
int main(void){
// TestStruct();
// TestUnion();
// TestEnum();
TestBool();
return 0;
}
缺省/默认参数
- 可以为函数的形参指定缺省 (默认) 值,这种参数称之为缺省参数
- 当调用该函数时若未指定实参,则使用形参的缺省(默认)值
- 如果函数的某一个形参具有缺省值,那么该形参后面的所有形参必须都具有缺省值
- 尽量避免因为使用缺省参数而导致重载匹配歧义
- 函数形参的缺省值只能在函数声明中指定
- 注意:默认值不是初始值
c++
// 函数的缺省参数: 带默认值的形参 (默认值不是初始值)
#include <iostream>
using namespace std;
void foo(int a, float b = 3.14, double c = 5.67, short d = 10, char e = 'A'); // 声明
void foo(int a, float b, double c, short d, char e){ // 定义
cout << "e: " << e << endl;
}
void foo(int i){
}
int main(void){
foo(12, 3.45, 6.78, 34); // 没有给第五个参数提供实参,所以使用缺省值
foo(12, 3.45, 6.78, 34, 'B'); // 给第五个参数提供了实参,使用实参
// foo(12); // 因为使用缺省参数,导致重载匹配歧义(不知道选择哪一个)
return 0;
}
问题
- 任何基本类型的数据,都可以隐式转换为布尔类型,那复合类型的数据,如何转换为布尔类型?