有C语言的基础,C++很好入门
C++教程
什么是命名空间namespace
命名空间是为了解决多个模块之间命名冲突的问题
#include <iostream>
using namespace std;
int main() {
cout<<"*******"<<endl;
cout<<"Hello World!"<<endl;
cout<<"*******"<<endl;
return 0;
}
其中count也可以通过域限定符 :: 来逐个制定
#include <iostream>
//using namespace std;
int main() {
std::cout<<"*******"<<std::endl;
std::cout<<"Hello World!"<<std::endl;
std::cout<<"*******"<<std::endl;
return 0;
}
输入和输出
- cout搭配<<表示输出,可使用多个<<,endl表示换行
- cin搭配>>表示读取从键盘的输入
#include <iostream>
using namespace std;
int main() {
int a;
cout<<"input string"<<endl;
cin>>a;
cout<<"get string is "<<a<<endl;
return 0;
}
输出为
input string
123
get string is 123
基本数据类型
- int、char、float、double分别表示整形、字符型、单精度、双精度
- 比C语言多了布尔类型bool,1表示true,0表示flase
#include <iostream>
using namespace std;
int main() {
int id;
char sex;
double score1 = 0, score2 = 0, score3 = 0;
bool isNO1;
cout << "please input ID, 'M' or 'W', score1, score2, score3" << endl;
cin >> id >> sex >> score1 >> score2 >> score3;
isNO1 = score1 > 12;
cout << "ID=" << id << ",sex=" << sex << ",total=" << score1 + score2 + score3 <<",isNo1="<<isNO1<<endl;
return 0;
}
运算符和表达式
- 算术运算符 +、-、*、%
- 自增自减运算符 ++、--
- 赋值运算符 =
- 关系运算符 >、<、>=、<=、!=、==
- 逻辑运算符 &&、||、!
/**
* 判断一个数是否为"水仙花数",所谓"水仙花数"是指这样的一个数:首先是一个三位数,
* 其次,其各位数字的立方和等于该数本身。例如:371是一个"水仙花数",371=3^3+7^3+1^3.
* @return
*/
int main() {
int a, ge, shi, bai;
cout << "input num >100" << endl;
cin >> a;
ge = a % 10;
shi = a % 100 / 10;
bai = a / 100;
cout << "ge=" << ge << ",shi=" << shi << ",bai=" << bai << endl;
if ((ge * ge * ge + shi * shi * shi + bai * bai * bai) == a) {
cout << 1 << endl;
} else {
cout << 0 << endl;
}
return 0;
}
输出为
input num >100
789
ge=9,shi=8,bai=7
循环结构
for循环、do while循环、while循环,结合break、continue
#include <iostream>
using namespace std;
int main() {
int a,b;
while (cin>>a>>b){
cout<<a+b<<endl;
}
return 0;
}
因为cin返回的是个istream的流对象,所以可以不断的遍历
1 2
3
4 5
9
7 8
15
...
函数的调用
#include <iostream>
#include <cstring>
using namespace std;
/**
* 反转字符串 123abc---->cba321
* @param a 原字符串
* @param b 反转后的字符串
* @return
*/
int reverse(char a[], char b[]) {
int n = strlen(a);
int i = 0;
while (a[i] != '\0') {
b[n - i - 1] = a[i];
i++;
}
b[n] = '\0';
return 0;
}
int main() {
char a[100];
char b[100];
cin >> a;
reverse(a, b);
cout << b << endl;
return 0;
}
带默认形参的函数
形参可以带默认函数
int main() {
cout<<add()<<endl;
cout<<add(1,9)<<endl;
cout<<add(5)<<endl;
return 0;
}
重载函数
和java一样,C++函数也可以重载
int add(int a = 2, int b = 6) {
return a + b;
}
double add(double a = 1, double b = 5) {
return a + b;
}
函数模板
类似java中的泛型,通过template来定义
#include <iostream>
using namespace std;
template<class T1, class T2>
T1 add(T1 a, T2 b) {
cout << sizeof(a) << " , " << sizeof(b) << "\t";
return a + b;
}
int main() {
cout << add(1, 5) << endl;
cout << add(1.2, 1.5) << endl;
cout << add('A', 2) << endl;
return 0;
}
4 , 4 6
8 , 8 2.7
1 , 4 C
内联函数inline
节省了函数的方法栈调用过程中的空间和时间,将函数完全展开在调用处
inline int Max(int a, int b) {
return a > b ? a : b;
}
int main() {
cout << Max(1, 2) << endl;
cout << Max(6, 5) << endl;
return 0;
}
类和对象
1.域限定符::
类名外的方法通过域限定符::来定义,但要在类中先定义好函数名称
class Person {
public:
int num;
char name[100];
double score;
int print();
};
int Person::print() {
cout << num << " " << name << " " << score << endl;
return 0;
}
相当于
class Person {
public:
int num;
char name[100];
double score;
int print() {
cout << num << " " << name << " " << score << endl;
return 0;
}
};
2.构造函数
C++有默认构造函数,也可以自定义
class Student {
private:
char name[100];
int num;
double score;
public:
Student(char *n, int num1, double score1);
void print();
};
Student::Student(char *n, int num1, double score1) {
strcpy(name, n);
num = num1;
score = score1;
}
void Student::print() {
cout<<name<<" "<<num<<" "<<score<<endl;
}
int main() {
Student A("xiaoming", 01, 98.7);
A.print();
return 0;
}
3.析构函数
- 函数前要加~
- 有默认函数,也可以自定义,随对象的销毁而调用
class Student {
private:
char name[100];
int num;
double score;
public:
Student(char *n, int num1, double score1);
~Student();
void print();
};
Student::Student(char *n, int num1, double score1) {
strcpy(name, n);
num = num1;
score = score1;
cout << name << " " << num << " " << score << " constructor" << endl;
}
Student::~Student() {
cout << name << " " << num << " " << score << " destructor" << endl;
}
void Student::print() {
cout << name << " " << num << " " << score << endl;
}
int main() {
Student A("this is A", 01, 98.7);
Student B("this is B", 02, 98.6);
return 0;
}
this is A 1 98.7 constructor
this is B 2 98.6 constructor
this is B 2 98.6 destructor
this is A 1 98.7 destructor
B析构函数比A先调用,因为局部变量在一个栈中,遵循“先进后出”的原则
4.拷贝构造函数
将对象引用作为函数的参数
class Circle {
private:
double R;
public:
Circle(double R);
Circle(Circle &circle);
};
Circle::Circle(double R) {
cout<<"constructor"<<endl;
this->R = R;
}
Circle::Circle(Circle &circle) {
cout<<"copy constructor"<<endl;
this->R = circle.R;
}
int main() {
Circle A(2);
Circle B(A);
return 0;
}
默认的拷贝构造函数是浅拷贝,自定义的是深拷贝,浅拷贝改变的是值,深拷贝改变的是内存地址
5.友元函数
在其他函数中,访问该类的函数,可以将该函数通过friend标记为友元函数
class Point {
private:
double x;
double y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
friend double getD(Point &a, Point &b);
};
double getD(Point &a, Point &b) {
double xx = a.x - b.x;
double yy = a.y - b.y;
return sqrt(xx * xx + yy * yy);
}
int main() {
Point A(1.0, 2.0);
Point B(2.0, 3.0);
double l = getD(A, B);
cout<<l<<endl;
return 0;
}
不加friend的话,main函数中是调用不了getD函数的
6.友元类
如果class B定义为class A的友元类的话,B就能访问A的私有变量,否则是访问不到的
class Point {
private:
double x;
double y;
public:
Point(double x, double y) {
this->x = x;
this->y = y;
}
friend class Tool;
};
class Tool {
public:
double getD(Point &point) {
double l = sqrt(point.x * point.x + point.y * point.y);
cout<<l<<endl;
return l;
}
};
int main() {
Point C(1.0, 2.0);
Tool tool;
tool.getD(C);
return 0;
}
7.常数
一.常数据成员
- 比如
int h,通过const int h或者int const h标明 - 常数成员变量需要通过构造函数指定默认值
Clock(int a) : h(a){
cout<<"constructor"<<endl;
}
- 通过static指定的const,必须在类外赋值
class Clock{
private:
const int h;
const int m;
int const s;
static const int x;
public:
Clock(int a,int b, int c) : h(a), m(b), s(c) {
cout<<"constructor"<<endl;
}
int getX() {
cout<<x<<endl;
return x;
}
};
const int Clock::x = 99;
int main() {
Clock A(1, 2, 3);
A.getX();
return 0;
}
二.常对象
常对象同样在生命周期内不可改变,可以通过构造函数赋值
const Clock A(1, 2, 3);
//A.getX(); 这行会报错
三.常函数
- 常函数只能访问成员变量,不可改写
int getX() const {
//x=66; 报错
cout << x << endl;
return x;
}
继承与派生
继承
- 继承面向父类,派生面向子类
- 通过冒号实现继承
class Person {
protected:
char name[100];
int sex;
public:
void setName(char *n) {
strcpy(name, n);
}
};
class Student: public Person {
public:
void setSex(int s) {
this->sex = s;
}
void getInfo() {
cout<<name<<" "<<sex<<endl;
}
};
int main() {
Student A;
A.setName("zhangsan");
A.setSex(0);
A.getInfo();
return 0;
}
派生类的构造函数
先调父类的构造函数,再调子类的构造函数
#include <iostream>
#include <cstring>
using namespace std;
class Person{
public:
char name[100];
int sex;
public:
Person(char *name,int sex) {
strcpy(this->name, name);
this->sex = sex;
cout<<"Person contructor"<<endl;
}
};
class Student: public Person {
public:
Student(char *n, int o) : Person(n, o) {
cout<<"Student contructor"<<endl;
}
};
int main() {
Student A("xiaoming", 1);
return 0;
}
析构函数的调用则是相反的,即先调用子类,再调用父类,因为依照栈的先进后出的原则
虚基类
C++允许多继承,继承多个父类时,需要在父类添加virtual,否则不知道用哪个父类的变量,引发二义性
class A {
public:
int key;
};
class B: virtual public A {
};
class C: virtual public A {
};
class D : public B, public C {
};
int main() {
D d1;
d1.key = 6;
return 0;
}
虚函数
虚函数用来解决多态的问题
class Point {
private:
int x;
int y;
public:
Point(int x = 0, int y = 0) {
this->x = x;
this->y = y;
}
virtual double area() {
return 0;
}
};
class Circle: public Point {
private:
int x1;
int x2;
int x3;
public:
Circle(int d,int e, int f) {
this ->x1 = d;
x2 = e;
x3 = f;
}
double area() {
return 3.14 * x1 * x2;
}
};
int main() {
Point A(10, 11);
cout<<A.area()<<endl;
Circle B(2, 6, 7);
cout<<B.area()<<endl;
Point *D;
D = &B;
cout<<D->area()<<endl;
Point &p = B;
cout<<p.area()<<endl;
return 0;
}
虚析构函数
通过给基类析构函数添加虚函数,来实现也调用其子类虚构函数的目的