C语言到C++入门
前言
很早以前就学了c语言,后来也学习了Java语言,突然想看看c++语言。也没想学的多深,毕竟C++是公认的难、不过我想有其他语言基础,学习一下基本语法应该相对简单的。
环境
g++
c++17
1、准备
C++ 是 C 的一个超集,事实上,任何合法的 C 程序都是合法的 C++ 程序。
经常看到的一句话是 c++就是 c with class
c++的文件扩展名是cpp.
2、结构
一个c++的语言结构如下:
- 头文件,
中含有c++的标准输入输出流 - 命名空间、用于管理模块,一个文件中可以有多个命名空间
#include <iostream>//头文件
using namespace std;//命名空间
void add(int *x,int y);//函数声明
int main()
{
int x=0;
add(&x,10);
cout<<x<<" end"<<endl;//标准输出流
string s;//字符串
cout<<"input string"<<endl;
cin>>s;//标准输入
cout<<"out "<<s;//换行
}
void add(int *x,int y){//函数
*x=*x+y;
}
这个文件使用了 iostream文件下的std命名空间。coutcin都是此文件std下的功能。>>箭头是流操作符。
3、命名空间
命名空间的使用即 spaceName::xxx
如果使用using关键字后,可以直接使用空间内的功能。
#include <iostream>
using namespace std;
#include<stdio.h>//c头文件
namespace ns_1{//命名空间1
const string ns="namespace_1";
void out(){
cout<<ns<<endl;
printf("ns_1
");//c的格式化输出
}
}
namespace ns_2{//命名空间2
const string ns="namespace_2";
void out(){
cout<<ns<<endl;
}
}
using namespace ns_1;//using使用命名空间
int main()
{
out();//ns_1的out()
ns_2::out();//ns_2的out()
}
4、引用
引用很容易与指针混淆,它们之间有三个主要的不同:
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。
int x=10;
int y=x;
cout<<"x: "<<x<<" y: "<<y<<endl;
y=7;
cout<<"x: "<<x<<" y: "<<y<<endl;
int&z=x;//引用
cout<<"x: "<<x<<" z: "<<z<<endl;
z=1;//修改引用
cout<<"x: "<<x<<" z: "<<z<<endl;
x: 10 y: 10
x: 10 y: 7
x: 10 z: 10
x: 1 z: 1
5、面向对象
c++支持面向对象,那么就有类的概念。
C++的类由成员变量、静态成员变量、成员函数、构造函数、析构函数、静态函数、友元函数、内联函数等构成。
类、构造、析构、成员函数、变量及修饰符
使用class关键字定义对象,使用public privateprotected关键字管理成员可见性。
#include<iostream>
using namespace std;
class Animal{
public:
int id;
int age;
string name;
Animal(){//无参构造
cout<<"init "<<endl;
}
~Animal();//析构函数,具体功能在外部实现
void info(){
cout<<id<<" "<<age<<" "<<name<<endl;
}
void sayHi();//成员函数声明,函数体在外部
};
Animal::~Animal(){//析构函数
cout<<" destory end====="<<endl;
}
void Animal::sayHi(){//外部实现函数功能
cout<<" hello "+name<<endl;
}
int main(){
Animal a;//声明对象
a.id=10010;//公开成员可直接访问
a.name="dog";
a.info();
cout<<a.id;
a.sayHi();
}
//this是类中的指针,指向当前对象、不能指向静态成员
静态成员
#include<iostream>
using namespace std;
class Animal{
public:
int id;
int age;
string name;
Animal(double height,double weight){//含参构造函数
this->height=height;
this->weight=weight;
cout<<"init end======="<<endl;
}
void sayHi();//成员函数
static string data;//成员变量
static void getData(){//静态成员函数
cout<<" get data ====="<<endl;
}
private:
double height;
double weight;
void show_HW(){//私有函数只能在类内部实现
cout<<"Animal's h: "<<height<<" w: "<<weight<<endl;
}
};
Animal::~Animal(){//析构函数
cout<<" destory end====="<<endl;
}
void Animal::sayHi(){//外部实现函数功能
cout<<" hello "+name<<endl;
this->show_HW();
}
string Animal::data="this is data";//给静态成员赋值
int main(){
Animal a(120.5,92.34);//声明对象
a.id=10010;
a.name="dog";
a.info();
cout<<a.id;
a.sayHi();
Animal::getData();//调用静态函数
}
6、继承
c++支持多继承、虚继承等。
基本继承形式如下:
class derived-class: access-specifier base-class
如:
class Cat :public Animal{
};
继承权限如下:
公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。
子类可以继承父类非函数,但父类的构造函数和析构函数不能被继承。
若想调用父类的构造函数,child_init():base_init(),析构函数只有一个,默认调用。如下:
class Cat :public Animal{
public:
Cat():Animal(){//调用父类的构造方法
cout<<"Cat init=="<<endl;
}
void sayHi(){//重写父类函数
cout<<"cat say hi"<<endl;
}
void sayHi(string name){//重载函数
this->name=name;
cout<<name;
this->sayHi();//this指针调用当前的sayHi()函数
}
};
int main(){
Animal a;//声明对象
a.name="dog";
Cat c;
c.sayHi("Tom");
Cat::getData();//调用父类的静态方法
}
init
init//子类调用的父类构造函数
Cat init==
Tomcat say hi
get data =====//父类的静态函数
Tomdestory end=====//继承自父类的析构函数
dogdestory end=====
//在主函数中末尾加入以下语句,输出结果发现对象的析构函数调用是按照栈特点来执行的。
Animal pig;pig.name="pig";//先进后出
7、多态
多态是面向对象的重要特性,多态的重要特性之一就是重载。
如上的函数重载以及运算符重载。
void sayHi(){//重写父类函数
cout<<"cat say hi"<<endl;
}
void sayHi(string name){//重载函数
this->name=name;
cout<<name;
this->sayHi();//this指针调用当前的sayHi()函数
}
8、动态内存
C中的指针内存是手动分配,C++中提供了new和delete关键字用于处理内存分配。
这种分配是动态的,但也是需要手动管理。
Cat* cat=new Cat;
cat->name="jim";
cat->sayHi();
delete cat;
如果不使用delete关键字,那么cat对象的析构方法就不会被执行,cat所占用的内存将不会及时得到释放。