c++核心编程和桌面应用开发3.1 1-1c++概述

本文介绍了C++语言的基础,包括C++的面向对象特性如封装、继承和多态,强调了命名空间的作用和使用,以及`::`作用域运算符。此外,详细讨论了`const`关键字的用法,包括在C和C++中的差异,并提倡使用`const`替代`#define`进行常量定义。还涉及了`using`声明和编译指令,以及struct类型的增强功能和类型转换规则。
摘要由CSDN通过智能技术生成

C++概述(了解)

c++语言在c语言的基础上添加了面向对象编程泛型编程的支持。c++继承了c语言高效,简洁,快速和可移植的传统。
c++融合了3种不同的编程方式:
 c语言代表的过程性语言.
 c++在c语言基础上添加的类代表的面向对象语言.
 c++模板支持的泛型编程。

C++初识

Hello World

 #include; 预编译指令,引入头文件iostream.
 using namespace std; 使用标准命名空间
 cout << “hello world”<< endl; 和printf功能一样,输出字符串”hello wrold”

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;//标准命名空间


int main()
{
	//cout是标准的输出流对象,打印字符串,
	//endl是刷新缓冲区,并换行
	cout << "hello world!" << endl;
	system("pause");
	return EXIT_SUCCESS;
}

面向对象三大特性

封装
把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
类将成员变量和成员函数封装在类的内部,根据需要设置访问权限,通过成员函数管理内部状态。
继承
继承所表达的是类之间相关的关系,这种关系使得对象可以继承另外一类对象的特征和能力。
继承的作用:避免公用代码的重复开发,减少代码和数据冗余。
多态
多态性可以简单地概括为“一个接口,多种方法”,字面意思为多种形态。程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。

命名空间(重点)

1.为什么有命名空间,是因为解决多人合作时取标识符是重命名的问题
2.什么是命名空间

namespace A{//A是空间的名字,
	int a;
	void func()
	{
	}
}

3.命名空间的注意
注意1:命名空间只能写在全局
注意2:命名空间可以嵌套命名空间

//命名空间可以嵌套命名空间
namespace Maker
{
	int a;
	namespace B
	{
		int b;
	}
}

注意3:命名空间是开放,随时可以加入新成员,但是新成员只能在加入后使用

namespace Maker
{
	int a;
	namespace B
	{
		int b;
	}
}
namespace Maker
{
	int c;
}

注意4:匿名命名空间

//类似于static int d=50;
namespace
{
	int d = 50;
}

注意5:命名空间可以取别名

void test01()
{
	//			新名字    旧名字
	namespace nameMaker = Maker;
	cout << nameMaker::a << endl;
}

注意6:分文件编写代码时,如果.h中有两个命名空间,但是里面的成员函数或成员变量同名时,在.cpp中实现函数时,需要加上命名空间

test.h文件
#pragma once
#include<iostream>
using namespace std;

namespace myMaker1
{
	void func();
}
namespace myMaker2
{
	void func();
}

test.cpp文件
#include "test.h"
void myMaker1::func()//需要在函数名前面加入确定命名空间名字
{
	cout << "func" << endl;
}

注意7: 命名空间可嵌套命名空间

namespace A{
	int a = 10;
	namespace B{
		int a = 20;
	}
}
void test(){
	cout << "A::a : " << A::a << endl;
	cout << "A::B::a : " << A::B::a << endl;
}

::作用域运算符

作用域运算符可以用来解决局部变量与全局变量的重名问题

//全局变量
int a = 10;
//1. 局部变量和全局变量同名
void test(){
	int a = 20;
	//打印局部变量a
	cout << "局部变量a:" << a << endl;
	//打印全局变量a
	cout << "全局变量a:" << ::a << endl;
}

using声明和编译指令(重点)

using声明是让命名空间中某个标识符可以直接使用

namespace A
{
	int a = 10;
	int b = 20;
	int c = 30;
}

void test01()
{
	//using声明是让命名空间中某个标识符可以直接使用
	using A::a;
	cout <<a << endl;
	//int a = 50;//注意:using声明了某个变量,在该作用域内不能定义同名的变量
}

using编译指令,让某个命名空间中的标识符都可以直接使用

namespace A
{
	int a = 10;
	int b = 20;
	int c = 30;
}
void test02()
{
	//using编译指令,让某个命名空间中的标识符都可以直接使用
	using namespace A;
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;

	int a = 100;//为什么不会冲突
	//类似于命名空中的a是全局变量,这里的a的局部变量
	cout << "a=" << a << endl;

}

struct类型加强

加强一:定义变量时不需要使用struct
加强二:结构体内可以写函数

//1. 结构体中即可以定义成员变量,也可以定义成员函数
struct Student{
	string mName;
	int mAge;
	void setName(string name){ mName = name; }
	void setAge(int age){ mAge = age; }
	void showStudent(){
		cout << "Name:" << mName << " Age:" << mAge << endl;
	}
};

//2. c++中定义结构体变量不需要加struct关键字
void test01(){
	Student student;
	student.setName("John");
	student.setAge(20);
	student.showStudent();
}

更严格的类型转换(了解)

不能隐性的转换,必须显示的转换

typedef enum COLOR{ GREEN, RED, YELLOW } color;
int main(){
	
	//以下c代码c编译器编译可通过,c++编译器无法编译通过。
	char* p = malloc(64);
	
	char* p = (char*)malloc(10);
	return EXIT_SUCCESS;
}

三目运算符(了解)

 c语言三目运算表达式返回值为数据值,为右值,不能赋值。

	int a = 10;
	int b = 20;
	printf("ret:%d\n", a > b ? a : b);
	//思考一个问题,(a > b ? a : b) 三目运算表达式返回的是什么?
	
	//(a > b ? a : b) = 100;
	//返回的是右值

 c++语言三目运算表达式返回值为变量本身(引用),为左值,可以赋值。

	int a = 10;
	int b = 20;
	printf("ret:%d\n", a > b ? a : b);
	//思考一个问题,(a > b ? a : b) 三目运算表达式返回的是什么?

	cout << "b:" << b << endl;
	//返回的是左值,变量的引用
	(a > b ? a : b) = 100;//返回的是左值,变量的引用
	cout << "b:" << b << endl;

[左值和右值概念]
在c++中可以放在赋值操作符(=)左边的是左值,可以放到赋值操作符右面的是右值。
有些变量即可以当左值,也可以当右值。
左值为Lvalue,L代表Location,表示内存可以寻址,可以赋值。
右值为Rvalue,R代表Read,就是可以知道它的值。
比如:int temp = 10; temp在内存中有地址,10没有,但是可以Read到它的值。

C/C++的const(重点)

1.C语言的const修饰的变量都有空间
2.C语言的const修饰的全局变量具有外部链接属性(使用extern来引用其他文件的常量
3.C++语言的const修饰的变量有时有空间,有时没有空间(发生常量折叠,且没有对变量进行取址操作)

const int aa = 10;//没有内存

void test01()
{
	//发生了常量折叠
	cout << "aa=" << aa << endl;//在编译阶段,编译器:cout<<"aa="<<10<<endl;

	//禁止优化volatile
	//volatile const int bb = 20;//栈区
	 const int bb = 20;
	int *p = (int*)&bb;//进行了取址操作,所以有空间
	*p = 200;
	cout << "bb=" << bb << endl;//cout << "bb=" << 20 << endl;
	cout << "*p=" << *p << endl;

	cout << "a的地址=" << (int)&bb << endl;
	cout << "p指向的地址" << (int)p << endl;
}

4.C++语言中const修饰的全局变量具有内部链接属性(只能在本文件中使用)
extern const int c = 300;//加上extern就变为外部链接属性(可以其他文件使用)

5.C++编译器不能优化的情况

1.不能优化自定义数据类型

2.如果用变量给const修饰的局部变量赋值,那么编译器就不能优化

3.编译器是在编译阶段来优化数据

C/C++中const异同总结

c语言全局const会被存储到只读数据段。c++中全局const当声明extern或者对变量取地址时,编译器会分配存储地址,变量存储在只读数据段。两个都受到了只读数据段的保护,不可修改。

const int constA = 10;
      int main(){
           int* p = (int*)&constA;
           *p = 200;
     }

以上代码在c/c++中编译通过,在运行期,修改constA的值时,发生写入错误。原因是修改只读数据段的数据。
 c语言中局部const存储在堆栈区,只是不能通过变量直接修改const只读变量的值,但是可以跳过编译器的检查,通过指针间接修改const值。

const int constA = 10;
	int* p = (int*)&constA;
	*p = 300;
	printf("constA:%d\n",constA);
	printf("*p:%d\n", *p);

运行结果:
在这里插入图片描述

c语言中,通过指针间接赋值修改了constA的值。
c++中对于局部的const变量要区别对待:

  1. 对于基础数据类型,也就是const int a = 10这种,编译器会进行优化将值替换到访问的位置。
	const int constA = 10;
	int* p = (int*)&constA;
	*p = 300;
	cout << "constA:" << constA << endl;
	cout << "*p:" << *p << endl;

运行结果:
在这里插入图片描述

  1. 对于基础数据类型,如果用一个变量初始化const变量,如果const int a = b,那么也是会给a分配内存。
	int b = 10;
	const int constA = b;
	int* p = (int*)&constA;
	*p = 300;
	cout << "constA:" << constA << endl;
	cout << "*p:" << *p << endl;

运行结果:
在这里插入图片描述

constA 分配了内存,所以我们可以修改constA内存中的值。
3. 对于自定数据类型,比如类对象,那么也会分配内存。

    const Person person; //未初始化age
	//person.age = 50; //不可修改
	Person* pPerson = (Person*)&person;
	//指针间接修改
	pPerson->age = 100;
	cout << "pPerson->age:" << pPerson->age << endl;
	pPerson->age = 200;
	cout << "pPerson->age:" << pPerson->age << endl;

运行结果:
在这里插入图片描述

为person分配了内存,所以我们可以通过指针的间接赋值修改person对象。

尽量用const替代define

1.define没有数据类型,const修饰的变量有数据类型,可以进行数据类型检查
#define MA 128
const short ma = 128;
void func(short a)
{
	cout << "func(short a)" << endl;
}

void func(int a)
{
	cout << "func(int a)" << endl;
}
int main()
{
	func(ma);
	system("pause");
	return EXIT_SUCCESS;
}
2.const修饰的变量有作用域,define不重视作用域,不能限定常量的使用范围
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值