前言——C与C++的关系
- C++可以与C代码进行混编,C++里面可以写C,但是反过来不可以。
- C++是面向对象编程语言、C是面向过程的编程。
- C++对C的一个增强。C++有class、引用的概念,堆内存的分配释放除了C语言的malloc、free,还有new、delete关键字。
C++的命名空间
基本概念
命名空间,也叫名字空间,类似于Java中包(归类)。当项目比较大的时候,用于区分不同人写的代码、不同库的代码。不同名字空间下面,函数名、变量名、类名等都可以重复。
最基本的例子:
#include <iostream>
using namespace std;
void main(){
cout << "我爱你" << endl;
system("pause");
}
这是一个Hello Word的例子,需要注意的地方有:
- 通过using namespace来使用std这个命名空间。也可以通过std::的方式来时用命名空间,::叫做访问修饰符。
- cout是头文件iostream的输出函数,C++中头文件的包含不需要写.h后缀。其中<<是运算符重载。endl是换行的意思。
自定义命名空间
通过namespace关键字来自定义命名空间:
#include <iostream>
using namespace std;
namespace name1{
int a = 1;
namespace name1_1{
int a = 3;
}
}
namespace name2{
int a = 2;
}
void main(){
cout << name1::a << endl;
cout << name2::a << endl;
cout << name1::name1_1::a << endl;
system("pause");
}
从上面的例子中可以看到,名字空间可以嵌套。
C++中的结构体、结构体与命名空间
-
C++是C的增强,C++中的结构体可以有访问修饰符,修饰符是多个变量或者函数共用的一个的。
-
C++中的结构体与Java中的类非常类似,在C语音中只能用函数指针当作成员函数,在C++中直接就是函数。
-
C++中的结构体有一个this指针,指向自身。
-
C++中通过using使用了命名空间之后,在使用结构体的时候,struct关键字可以省略。
include <iostream>
using namespace std;
namespace name1{
struct Teacher{ private: char* name; public: int age; void say(){ cout << "Hello My age is :" << this->age << endl; } };
}
void main(){
using name1::Teacher; Teacher t; t.age = 20; system("pause");
}
C++中的类
#include <iostream>
using namespace std;
class AClass
{
public:
int getA(){
//return this->a;
return a;
}
void setA(int a){
this->a = a;
}
private:
int a;
};
void main(){
AClass c;
c.setA(4);
cout << c.getA() << endl;
system("pause");
}
注意:
- 与Java类似,有一个tihs指针指向自身。
- 类的定义末尾需要有分号。
- 这里的main函数中的c是存在于栈内存的,可以通过new关键字在堆内存中创建对象的实体,但是我们需要
C++中的布尔类型
C++中有布尔类型bool,C语言没有。
#include <iostream>
using namespace std;
void main(){
bool b = true;
if (b){
cout << b << endl;
cout << sizeof(bool) << endl;
}
system("pause");
}
bool的值有true、false,实质是1和0,占一个字节大小。
在C/C++中,条件表达式中,大于0就为真,小于等于0就为假。而Java中只能用true和false。
C++中的函数
函数参数可以有默认值,与PHP一样。
void test1(int a = 10){
}
一旦某个参数值定了默认值,那么后面的所有参数都需要有
void test2(int a, int b = 10, int c = 20){
}
函数重载的时候需要注意二义性。
函数的可变参数
需要使用头文件stdarg.h。
-
通过va_start开始读取可变参数,其中形参i是最后一个固定参数。
-
通过va_arg读取,需要指定类型。
-
通过va_end结束读取。
include <iostream>
include <stdarg.h>
using namespace std;
void test(int i, ...){
va_list args_p; va_start(args_p, i); //开始读取 int a = va_arg(args_p, int); char b = va_arg(args_p, char); int c = va_arg(args_p, int); va_end(args_p); cout << a << endl; cout << b << endl; cout << c << endl;
}
void main(){
test(1, 10, 'a', 20);
system("pause");
}
也可以循环读取,但是需要有条件(比如可变参数都大于0),且可变参数的类型都一样,例子:
void test(int i, ...){
va_list args_p;
va_start(args_p, i);
//开始读取
while (true){
int a = va_arg(args_p, int);
if (a <= 0){
break;
}
cout << a << endl;
continue;
}
va_end(args_p);
}
void main(){
test(1, 10, 20, 30, -1);//-1相当于结束符
system("pause");
}
C++中类的写法
定义一般写在头文件中,实现在源文件中,例如:
头文件:
#pragma once
class Teacher
{
public:
Teacher();
~Teacher();
};
源文件:
#include "Teacher.h"
Teacher::Teacher()
{
}
Teacher::~Teacher()
{
}
使用:
#include "Teacher.h"
void main(){
Teacher t;
system("pause");
}
C++中的函数模板
模板函数,相当于Java中的泛型。
例如,为了实现两个东西交换,可以实现两个函数:
void myswap(int& a,int& b){
int tmp = 0;
tmp = a;
a = b;
b = tmp;
}
void myswap(char& a, char& b){
char tmp = 0;
tmp = a;
a = b;
b = tmp;
}
但是我们发现:这两个函数业务逻辑一样,数据类型不一样,因此这个时候就可以使用函数模板来减少代码量:
template <typename T>
void myswap(T& a, T& b){
T tmp = 0;
tmp = a;
a = b;
b = tmp;
}
void main(){
//根据实际类型,自动推导(当然,也可以指定类型,跟Java很类似)
int a = 10, b = 20;
myswap<int>(a,b);
cout << a << "," << b << endl;
char x = 'v', y = 'w';
myswap(x, y);
cout << x << "," << y << endl;
system("pause");
}
模板类
自定义模板类
template<class T>
class A{
public:
A(T a){
this->a = a;
}
protected:
T a;
};
自定义普通类继承模板类
class B :public A<int>{
public:
B(int a)
:A<int>(a){
}
};
自定义模板类继承模板类
template<class T>
class C :public A<T>{
public:
C(int a)
:A<T>(a){
}
};
模板类的实例化
A<int> a(10);
如果觉得我的文字对你有所帮助的话,欢迎关注我的公众号:
公众号:Android开发进阶我的群欢迎大家进来探讨各种技术与非技术的话题,有兴趣的朋友们加我私人微信huannan88,我拉你进群交(♂)流(♀)。
网友评论
template<class T>
class C :public A<T>{
public:
C(int a)
:A<T>(a){
}
};
是不是应该写成
template<class T>
class C :public A<T>{
public:
C(T a)
:A<T>(a){
}
};
c++知识比较欠缺,请指教。