在 C++ 中,头文件不再以.h结尾,例如下一节提到的头文件 iostream。一些C语言中常用的头文件在 C++ 中的名字变为去掉.h,并在开头增加字符c。例如:
#include
#include
#include
#include
using namespace std;
int main()
{
int a;
char name[20];
cin >> a >> name;
cout << a << ' ' << name << endl;
return 0;
}
命名命名空间语法格式
namespace namespace_name {
//代码声明
}
调用命名空间中成员的语法格式
namespace_name::code; //code 可以是变量或函数
举例
namespace Ui
{
class frmMain;
}
Ui::frmMain *ui;
void Func(int x=20); //函数的声明中,指明参数 x 的默认值是 20
Func(); //正确的调用语句,等效于 Function1(20);
int Max(int m, int n);
int a, b;
void Func(int x, int y=Max(a,b), int z=a*b){
...
}
Func(4); //正确,等效于 Function2(4, Max(a,b), a*b);
Func(4, 9); //正确,等效于 Function2(4,9 , a*b);
Func(4, 2, 3); //正确
Func(4, ,3); //错误!这样的写法不允许,省略的参数一定是最右边连续的几个
void fun(int one, int two = 2);
void fun(int one);
inline int Max (int a, int b)
{
if(a >b)
return a;
return b;
}
#include
#include
using namespace std;
void Max(int a, int b)
{
cout << "Max 1" << endl;
}
void Max(double a, double b)
{
cout << "Max 2" << endl;
}
void Max(double a, double b, double c)
{
cout << "Max 3" << endl;
}
int main()
{
Max(3, 4); //调用 void Max(int, int)
Max(2.4, 6.0); //调用 void Max(double,double)
Max(1.2, 3.4, 5); //调用 void Max(double, double, double)
Max(1, 2, 3); //调用 void Max(double, double, double)
void (*ptr1)(int, int) = Max;
printf("%p\n", ptr1); //打印int Max(int, int)函数的首地址
void (*ptr2)(double, double) = Max;
printf("%p\n", ptr2); //打印void Max(double,double)函数的首地址
void (*ptr3)(double, double, double) = Max;
printf("%p\n", ptr3); //打印void Max(double, double, double)函数的首地址
//Max(3, 1.5); //编译出错:二义性
return 0;
}
#include
using namespace std;
class A
{
public:
void test()
{
cout << "void test()" << endl;
}
void test() const
{
cout << "void test() const" << endl;
}
};
int main()
{
A a1;
a1.test();
const A a2;
a2.test();
}
#include
#include
#include
int main()
{
int *ptr1 = (int *)malloc(2 * sizeof(int));
printf("%p\n", ptr1);
int *a = new int(10);
printf("%p\n", &a);
int *ptr2 = (int *)malloc(2 * sizeof(int));
printf("%p\n", ptr2);
int *b = new int(10);
printf("%p\n", &b);
return 0;
}
/* new & malloc */
int *pi = new int; //该new表达式在自由存储区中分配创建了一个整形对象,
//并返回一个指向该对象的地址来初始化指针pi
int *pi = new int(); //同上并初始化为0
int *pi = new int(1024); //同上并初始化为1024
delete pi; //释放pi指向的int型对象所占用的内存空间
p = NULL; //pi已经无效,但是还在,置为0,清楚的表明指针不再指向任何对象,不然容易野指针
const int *pi = new const int(1024); //动态创建的const对象必须进行初始化,
//并且进行初始化后的值不能再改变
//数组动态内存分配
int *pi = new int[]; //指针pi所指向的数组未初始化
int *pi = new int[n]; //指针pi指向长度为n的数组,未初始化
int *pi = new int[](); //指针pi所指向的地址初始化为0
delete [] pi; //回收pi所指向的数组
/* malloc & free */
void *malloc(size_t size); //头文件为stdlib.h
void free(void *pointer); //头文件为stdlib.h
//示例
int *p = (int *)malloc(10); //指向整型的指针p指向一个大小为10字节的内存的地址
int *p = (int *)malloc(5 * sizeof(int)); //指向整型的指针p指向一个5个int整型空间的地址
//free释放
int *p=(int *)malloc(int);
if(pi == NULL)
printf("Out of memory!\n");
free (p);
p = NULL;
用字符数组存放字符串容易发生数组越界的错误,而且往往难以察觉。因此,C++ 标准模板库设计了 string 数据类型,专门用于字符串处理。string 并不是 C++ 的基本数据类型,它是 C++ 标准模板库中的一个“类”
string 变量名;
string str1; //定义 string 对象 str1,未初始化,值为空串“”
string city = "Suzhou"; //定义 string 对象 city,并初始化
/* 定义 string 对象数组 */
string as[] = {"Suzhou", "Lianyungang", "Taiyuan"};
cout << as[1]; //输出 Lianyungang
/* string对象的输入输出 */
string str1, str2;
cin >> str1 >> str2;
cout << str1 << " " << str2;
char name[] = "Lady Gaga";
string s1 = name; //赋值后s1中的内容和name相同,修改s1不会影响name
/* 运算 */
string s1 = "123", s2 = "abc", s3; //s3是空串
s3 = sl + s2; //s3 变成"123abc"
s3 += "de"; //s3 变成"123abcde"
bool b = s1 < s3; //b 为 true
char c = s1[2]; //c变成'3'(下标从0开始计算)
s1[2] = '5'; //s1 变成”125"
宋丹丹问赵本山:“把大象装进冰箱,需要几步?”
<C:面向过程>
第一步,打开冰箱
第二步,把大象塞进去
第三步,关上冰箱
<C++:面向对象>
第一步,把大象装冰箱实现为类的一个功能
第二步,调用该类,完成任务
class 类名
{
访问范围说明符:
成员变量1
成员变量2
成员函数声明1
成员函数声明2
访问范围说明符:
更多成员变量
更多成员函数声明
...
};
“访问范围说明符”一共有三种,分别是 public、private 和 protected
类外实现成员函数
返回值类型 类名::函数名()
{
函数体
}
#include
using namespace std;
class Square
{
public:
int area();
void init(int l, int w);
protected:
int length;
int width;
};
void Square::init(int l, int w)
{
length = l;
width = w;
}
int Square::area()
{
return (length * width);
}
int main()
{
Square squ;
squ.init(8, 8);
cout << squ.area() << endl;
}
成员访问
. :对应实体
>:对应指针
创建
对象指针:类名 *对象指针名;
#include
#include
using namespace std;
class A
{
public:
A()
{
cout << "A()" << endl;
width = 1;
}
A(int a)
{
cout << "A(int a)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
void func();
int width;
private:
int length;
};
void A::func()
{
cout << "void func();" << endl;
}
int main()
{
A a1;
printf("%p\n", &a1);
A a2(100);
printf("%p\n\n", &a2);
A a3();
//printf("%p\n", &a3); //没有分配地址运行出错
//A a1 = A; //错误的
A b2 = A(100);
printf("%p\n", &b2);
A b3 = A();
printf("%p\n\n", &b3);
cout << "****对象指针****" << endl;
A *c1 = new A;
printf("%p\n", &c1);
A *c2 = new A();
printf("%p\n", &c2);
A *c3 = new A(100);
printf("%p\n\n", &c3);
cout << "****空间大小****" << endl;
printf("%d\n", sizeof(A)); //打印出类所占空间大小,无成员变量,值是1
printf("%d\n", sizeof(a1)); //打印出对象所占空间大小
printf("%d\n\n", sizeof(c1)); //打印出对象指针所占空间大小(固定,同指针大小)
cout << "****对象指针指向****" << endl;
A *d1 = NULL; //声明了对象指针,没有初始化,与c1不同
d1 = c1; //1、d1指向同一个对象
printf("%p\n",&(d1->width));
printf("%p\n",&(c1->width));
d1 = new A; //初始化
cout << "****访问****" << endl;
a1.func();
cout << a1.width <func();
(*c1).func();
cout << c1->width <
#include
using namespace std;
class CRectangle
{
private:
int w, h;
static int totalArea; //矩形总面积
static int totalNumber; //矩形总数
public:
CRectangle(int w_, int h_);
CRectangle(CRectangle & r)
~CRectangle();
static void PrintTotal();
};
CRectangle::CRectangle(CRectangle & r)
{
totalNumber++;
totalArea += r.w * r.h;
w = r.w; h = r.h;
}
CRectangle::CRectangle(int w_, int h_)
{
w = w_; h = h_;
totalNumber++; //有对象生成则增加总数
totalArea += w * h; //有对象生成则增加总面积
}
CRectangle::~CRectangle()
{
totalNumber--; //有对象消亡则减少总数
totalArea -= w*h; //有对象消亡则减少总而积
}
void CRectangle::PrintTotal()
{
cout << totalNumber << "," << totalArea << endl;
}
int CRectangle::totalNumber = 0;
int CRectangle::totalArea = 0;
//必须在定义类的文件中对静态成员变量进行一次声明 //或初始化,否则编译能通过,链接不能通过
int main()
{
CRectangle r1(3, 3), r2(2, 2);
//cout << CRectangle::totalNumber; //错误,totalNumber 是私有
CRectangle::PrintTotal();
r1.PrintTotal();
return 0;
}
类名::构造函数名(参数表): 成员变量1(参数表), 成员变量2(参数表), ...
{
...
}
#include
using namespace std;
class CTyre //轮胎类
{
private:
int radius; //半径
int width; //宽度
public:
CTyre(int r, int w) : radius(r), width(w) { }
};
class CEngine //引擎类
{
};
class CCar { //汽车类
private:
int price; //价格
CTyre tyre;
CEngine engine;
public:
CCar(int p, int tr, int tw);
};
CCar::CCar(int p, int tr, int tw) : price(p), tyre(tr, tw)
{
};
int main()
{
CCar car(20000, 17, 225);
return 0;
}
#include
using namespace std;
class A
{
public:
A(): ID(22), age(18)
{
cout << "A(): ID(22)" << endl;
tmp = 66;
this->tmp = 88;
this->output();
}
void output()
{
cout << "void output()" << endl;
}
int tmp;
protected:
int age;
private:
int ID;
};
int main()
{
A a1;
cout << a1.tmp << endl;
//cout << a1.age << endl;
//cout << a1.ID << endl;
}
C++中,构造函数与类名相同,析构函数前面加一个波浪线。析构函数,可以进行资源释放。都不需要写返回值。
#include
#include
using namespace std;
/**
* 定义类:Student
* 数据成员:m_strName
* 无参构造函数:Student()
* 有参构造函数:Student(string _name)
* 拷贝构造函数:Student(const Student& stu)
* 析构函数:~Student()
* 数据成员函数:setName(string _name)、getName()
*/
class Student
{
public:
Student() {
m_strName = "jack";
cout<<"Student()"<getName()<< endl;
// 更改对象的数据成员为“苏州”
stu1->setName("苏州");
// 打印对象的数据成员
cout<getName()<
#include
using namespace std;
class A
{
public:
A(int tmp): numb(tmp) //带参数构造函数
{
cout<< "A(int tmp): numb(tmp)"<
(1)C中变量
(2)C++ 类中
class A中如下直接声明赋值:
#include
using namespace std;
class Test {
public:
Test()
{
cout << "Test()" << endl;
}
~Test()
{
cout << "~Test()" << endl;
}
};
int main()
{
Test test;
cout << "main()" << endl;
}
//打印结果是如下
// Test()
// ~Test()
// main()
运算符重载:如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。有时希望对象之间也能用这些运算符进行运算,以达到使程序更简洁、易懂的目的。例如,复数是可以进行四则运算的,两个复数对象相加如果能直接用+运算符完成,不是很直观和简洁吗
返回值类型 operator 运算符(形参表)
{
....
}
#include
using namespace std;
class Complex
{
public:
double real, imag;
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { }
Complex operator - (const Complex & c);
};
Complex operator + (const Complex & a, const Complex & b)
{
return Complex(a.real + b.real, a.imag + b.imag); //返回一个临时对象
}
Complex Complex::operator - (const Complex & c)
{
return Complex(real - c.real, imag - c.imag); //返回一个临时对象
}
int main()
{
Complex a(4, 4), b(1, 1), c;
c = a + b; //等价于 c = operator + (a,b);
cout << c.real << "," << c.imag << endl;
cout << (a - b).real << "," << (a - b).imag << endl; //a-b等价于a.operator - (b)
return 0;
}
两步走
- 确定是否能继承
- 能继承的成员,属性由继承属性和基类的成员属性决定(取权限最高的)
#include
using namespace std;
class A
{
public:
int pub;
void publ()
{
cout << "void publ()" << endl;
}
A()
{
pub = 1;
pro = 2;
pri = 3;
}
void getValue()
{
cout << this->pub << endl;
cout << this->pro << endl;
cout << this->pri << endl;
this->publ();
this->prot();
this->priv();
}
protected:
int pro;
void prot()
{
cout << "void prot()" << endl;
}
private:
int pri;
void priv()
{
cout << "void priv()" << endl;
}
};
class B: public A
{
public:
void getValue1()
{
cout << this->pub << endl;
cout << this->pro << endl;
//cout << this->pri << endl; //私有成员不能继承
this->publ();
this->prot();
//this->priv(); //私有成员不能继承
}
};
class C: public B
{
public:
void getValue2() // B public、protected 继承 A,运行没问题
{
cout << this->pub << endl;
cout << this->pro << endl;
//cout << this->pri << endl; //私有成员不能继承
this->publ();
this->prot();
//this->priv(); //私有成员不能继承
}
};
int main()
{
cout << "****A****" << endl;
A a;
a.getValue();
cout << a.pub << endl;
a.publ();
//cout << a.pro << endl; //类外不能访问protected成员
//a.prot(); //类外不能访问protected成员
//cout << a.pri << endl; //类外不能访问private成员
//a.priv(); //类外不能访问private成员
cout << "****B****" << endl;
B b;
b.getValue1();
//cout << b.pub << endl; //public继承可以访问
//b.publ(); //public继承可以访问
cout << "****C****" << endl;
C c;
cout << c.pub << endl; // B: public A 可以访问,
}
- 对象的创建一定需要初始化
- 派生类继承父类时会涉及成员变量的继承,创建子类的对象时,便涉及父类成员变量的初始化。
#include
using namespace std;
class Person
{
public:
Person(int id, int ag)
{
ID = id;
age = ag;
}
int getBaseInfo()
{
cout << ID << endl;
cout << age << endl;
}
private:
int ID;
int age;
};
class Stu: public Person
{
public:
Stu(int gra, int id, int ag): Person(id, ag)
{
grade = gra;
cout << "Stu(int gra, int id, int ag): Person(id, ag)" << endl;
}
Stu(int gra): Person(320721, 18)
{
grade = gra;
cout << "Stu(int gra): Person(320721, 18)" << endl;
}
int getStuInfo()
{
cout << grade << endl;
}
private:
int grade;
};
int main()
{
Stu stu1(6, 320721, 18);
stu1.getBaseInfo();
stu1.getStuInfo();
cout << "**********"<< endl;
Stu stu2(6);
stu2.getBaseInfo();
stu2.getStuInfo();
}
#include
#include
using namespace std;
class Father
{
public:
void Face()
{
cout << "Father's face" << endl;
}
virtual void Say()
{
cout << "Father say hello" << endl;
}
};
class Son: public Father
{
public:
void Say()
{
cout << "Son say hello" << endl;
}
};
int main()
{
Son son;
Father *pFather = &son; // 隐式类型转换
pFather->Say();
}
多态同一个行为具有多个不同表现形式或形态的能力。是指一个类实例(对象)的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
多态的优点:
1、消除类型之间的耦合关系
2、可替换性
3、可扩充性
4、接口性
5、灵活性
6、简化性
多态存在的三个必要条件:
1、继承
2、重写(子类继承父类后对父类方法进行重新定义)
3、父类引用指向子类对象
简言之,多态其实是在继承的基础上的。比如说今天我们要去动物园参观动物,那么你说我们去参观兔子、参观绵羊、参观狮子、参观豹子都是对的,但你不能说我们去参观汽车。在这个例子中,子类具有多态性:除了使用自己的身份,还能充当父类。
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。
具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,这个时候,B不应当直接使用A中的具体类: 而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能 造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来
template ret-type func-name(parameter list)
{
// 函数的主体
}
#include
#include
using namespace std;
template inline T const& Max (T const& a, T const& b)
{
return a < b ? b : a;
}
//template T Max (T a, T b)
//{
// return a < b ? b : a;
//}
int main ()
{
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
template class class-name {
.
.
}
#include
#include
#include
#include
#include
using namespace std;
template
class Stack {
private:
vector elems; // 元素
public:
void push(T const&); // 入栈
void pop(); // 出栈
T top() const; // 返回栈顶元素
bool empty() const{ // 如果为空则返回真。
return elems.empty();
}
};
template
void Stack::push (T const& elem)
{
// 追加传入元素的副本
elems.push_back(elem);
}
template
void Stack::pop ()
{
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// 删除最后一个元素
elems.pop_back();
}
template
T Stack::top () const
{
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// 返回最后一个元素的副本
return elems.back();
}
int main()
{
try {
Stack intStack; // int 类型的栈
Stack stringStack; // string 类型的栈
// 操作 int 类型的栈
intStack.push(7);
cout << intStack.top() <
#ifndef IROBOT_H
#define IROBOT_H
......
void on_pb_control_clicked(); /* 控制界面触发 */
......
#endif // IROBOT_H
Class a
{
private:
int _ID; //私有成员,加_区别明显,具体各自公司代码规范或者是自己的编码风格
};
class <派生类名>:<继承方式><基类名>
{
<派生类新定义成员>
};
多态:“动态绑定”
是指子类重新定义父类的虚方法(virtual,abstract)。当子类重新定义了父类的虚方法后,父类根据赋给它的不同的子类,动态调用属于子类的该方法,这样的方法调用在编译期间是无法确定的。
重载:“静态绑定”
是指允许存在多个同名方法,而这些方法的参数不同。重载的实现是:编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。
课程管理系统设计(windows系统)
下载链接
1、C++入门教程,C++基础教程
2、cppreference
3、cplusplus
4、C++默认参数与函数重载 注意事项
5、面向对象的三大基本特征,五大基本原则
6、面向对象三大特性五大原则 + 低耦合高内聚
7、C++ 三大特性 封装,继承,多态
8、面向对象五大原则
9、浅谈new/delete和malloc/free的用法与区别
10、《C++程序设计》[第四版],作者谭浩强
11、《C++大学教程》[第九版],作者 Harvey M.Deitel Paul James Deitel
12、C++ 自由存储区是否等价于堆?
13、野指针及c++指针使用注意点
14、C++中的string详解
15、面向对象与面向过程的本质的区别
16、浅谈面向对象的编程思想:如何优雅地把大象装进冰箱?
17、C++类的成员函数(在类外定义成员函数、inline成员函数)
18、关于C++类的inline 成员函数
19、C++ 的浅拷贝和深拷贝(结构体)
20、C++面试题之浅拷贝和深拷贝的区别
21、c++深拷贝和浅拷贝
22、深入理解C++中public、protected及private用法
23、你必须知道的指针基础-8.栈空间与堆空间
24、C++继承中关于子类构造函数的写法
25、C++的初始化列表(Initilization List)
26、C++普通变量、C++静态成员变量、C++成员常量、C++静态成员常量的初始化方法
27、C++之友元机制(友元函数和友元类)
28、为什么复制构造函数的参数需要加const和引用
29、课程管理系统设计(windows系统)
30、关于C++类的静态数据为什么一定要初始化
31、c++中的抽象概念详解