输出
helloworld
<< "hello world" << endl; cout
头文件
declaration(.h) 和 definition(.cpp)任何的类都应该成对出现
02test.cpp # c预处理器
cpp ++ 02test.cpp --save-temp #保留编译过程中的中间过程文件
g.ii (编译预处理后的结果)
.s(汇编代码)
.o(目标代码)
.out(最终可执行程序)
++ 02test.cpp --save -c # 只编译不链接
g++ 02test.cpp --save-temps # 保留编译过程中的 .o 文件(给人看的)
g++ 02test.cpp 03test.cpp --save-temps -Wall # 打印所有warning g
标准头文件程序:
为了一个头文件(xxx.h
)只能被一次引入,不能重复的引入
#ifndef __LIST_HEAD__#define __LIST_HEAD__
"node.h"
#include
struct _list
typedef {
*head;
Node *tail;
Node } List;
#endif
双冒号作用域运算符
using namespace std; # 这里很关键否则cot,endl无法使用
int a=10;
void h(){
int a=20;
<< a << endl; # 20
cout << ::a<< endl; # 10
cout }
有点类似匿名函数,匿名内部类的感觉
void h(){
int a=20;
::cout << a << std::endl; # 20 这里就不用using namespace std了
std::cout << ::a<< std::endl; # 10
std}
地址输出
int a = 0;
const char * p = "hello";
<< "变量a的地址: " << &a << endl; // 变量a的地址
cout << "变量a的地址: " << static_cast<void *>(&a) << endl; // 变量a的地址
cout << "字符串 " << p << endl; // 字符串内容,即"hello"
cout << "字符串的地址 " << static_cast<const void *>(p) << endl; // 字符串的地址 cout
本地变量,成员变量
参考地址:https://blog.csdn.net/smile_from_2015/article/details/50189797 参考地址:https://blog.csdn.net/du_minchao/article/details/48881637
成员变量
(实例变量) 成员变量随着对象的建立而建立,随着对象的消失而消失,在类中可以随意使用
(实例化对象后会有成员变量)
本地变量
(局部变量) 在方法体
中任何位置都可以访问
本地变量: 成员变量:可以在函数中随意访问.
++ -m32 a.cpp // 32位系统 g
相同的类(对象)使用同一个function,同一个类 不同的对象调用同一个函数时,函数里面知道是哪个对象在调用他 ( 实现的方式*this
隐藏的变量 )
"iostream"
#include using namespace std;
class A{
public:
int i;
void f();
};
struct B{
int i;
};
void A::f(){
=20;
i<< i << endl;
cout << "A::f().i" << static_cast<void *>(&i) << endl;
cout << "this" << static_cast<void *>(this) << endl;
cout }
void f(struct B* p){
->i=200;
p<< p->i << endl;
cout
}
int main(){
;
A a;
B b;
A aa.i = 10;
a<< a.i << endl;
cout << "&a \t" << static_cast<void *>(&a)<<endl;
cout << "&a.i\t" << static_cast<void *>(&a.i) << endl;
cout // cout << b.i << endl;
.f();
a.f();
aaf(&b);
}
构造函数constructor
为什么要有构造函数
因为c语言和其他的语言(java,python)不太一样,c++自己不会对内存初始化,为了提升效率,让程序员自己去初始化内存,
#
,两个0xcb连起来(国标码)就会显示中文的烫,就以为着没有初始化的内存
# vsStudio的debug模式会填充0xcb
,然程序员去初始化内存,于是就出来了constructor就应需而生. # 为了规范程序员的代码
构造函数, 没有返回类型,在这个对象被创建的时候自动被调用
class x {
int i;
public:
X(); // 这里的名字要和class的名字一样(大小写也一致)
}; // 这里的这个 ; 很重要
构造函数demo
"iostream"
#include
using namespace::std;
class Tree{
public:
Tree(int length);
int init_length;
};
::Tree(int length){
Tree= length;
init_length << "inside Tree structor" << endl;
cout }
int main(){
<< " ------stat----" << endl;
cout { // scope start
<< "create Tree before" << endl;
cout t(12);
Tree << "create Tree after" << endl;
cout }// scope end
<< " ----- end ----" << endl;
cout return 0;
}
析构函数
释放掉之前构造函数申请的内存空间析构函数没有参数
class x {
int i;
public:
~X();
};
析构函数demo
"iostream"
#include
using namespace::std;
class Tree{
public:
Tree(int length);
int init_length;
~Tree();// 析构函数 Destructor
};
::Tree(int length){
Tree= length;
init_length << "inside Tree structor" << endl;
cout }
::~Tree(){
Tree<< static_cast<void *>(this) << endl;
cout }
int main(){
<< " ------stat----" << endl;
cout {
t(12);
Tree } // 析构函数的作用域scope,出了这个大括号就会调用析构函数.
<< "create Tree after" << endl;
cout << " ----- end ----" << endl;
cout return 0;
}
动态内存分配
c
语言的动态内存分配是 malloc
和 free
在c++
中采用的是: new
(生成对象)和delete
(回收对象)
new
1.分配空间 2.调用构造函数(自定义类) 3.返回一个地址()
new int # new Type 分配一个type类型的空间出来
new Class # new Class 分配一个对象给出来.
new int[10] # new Type[n] 分配n个type空间出来
delete
把内存还给内存池. delete的时候先调用析构函数,然后内存空间才会被回收.
; # 回收单个内存
delete p[] p; # 回收一组内存 delete
delete demo
要点: 1: 不要用delete去释放不是 new 分配出来的内存
2: 不要delete同一个空间两次
3: delete 可以安全的删除一个空指针(int * p = 0;)
4: 数组的时候一定要用数组[]类型delete
"iostream"
#include
using namespace::std;
class A{
private:
int i;
public:
//int i;
A(){
<< "A::A()" << endl;
cout }
~A(){
<< "~A" << i << endl;
cout }
void set(int i){
this->i=i;
}
void f(){
<< "hello" << endl;
cout }
};
int main(){
* p = new A[10];
Afor (int i=0;i<10;i++){
[i].set(i);
p}
[] p;// 释放内存
deletereturn 0;
}
访问限制
public:公开的,任何人都可以访问; protected:子孙类可以访问; private:只有自己可以访问。)(同一个类之内可以访问,成员函数…) friend : 可以互相访问 这个限制只有在编译阶段有效, 运行时刻没有限制
代码有点烂,不具备参考
"iostream"
#include
using namespace::std;
class A{
private:
int i;
public:
//int i;
A(){
<< "A::A()" << endl;
cout }
~A(){
<< "~A" << i << endl;
cout }
void set(int i){
this->i=i;
}
void f(){
<< "hello" << endl;
cout }
void g(A* p2){
<< "p2->i is :" << p2->i << endl;
cout }
};
int main(){
* p = new A[10];
Afor (int i=0;i<10;i++){
[i].set(i);
p[i].g(&p[i]);
p}
[] p;//
deletereturn 0;
}
friend demo
"iostream"
#include
using namespace::std;
struct A;
struct B{
void f(A*);
};
struct A{
private:
int i;
public:
void hello();
void g(A*, int);
friend void B::f(A*);
friend struct Z;
friend void h();
friend };
void A::hello(){
=100;
i<< "成员访问变量:" << i << endl;
cout }
void g(A* a, int i){
->i = i;
a<< "friend 方法访问:" << i << endl;
cout }
void B::f(A* a){
->i=999;
a<< "B中函数修改A中i: "<< a->i<< endl;
cout }
struct Z{
private:
int j;
};
void h(){
<<"hello" <<endl;
cout }
int main(){
;
A a.hello();
a;
A a.hello();
a
return 0;
}
class和struct的区别
class
默认的是private
struct
默认是public
# 初始化列表(推荐) 初始化列表不要被名字唬住,其实就是是相当于在初始化之前给了一个默认值,赋值的过程提到了构造器之前.格式: Class(): key(value)
推荐类在初始化列表中做初始化,不要要构造器中做赋值
"iostream"
#include
using namespace::std;
class Student{
public:
int age;
string name;
Student():age(12),name("tom"){};
};
int main(){
;
Student a<< a.name << endl;
cout << a.age << endl;
cout return 0;
}
组合和继承
组合是对象进行拼装,是存在对象的 继承是类进行拼装,是没有真实的存在的 c++中的组合适类的组合,不是对象的组合
### interface 对外公开的部分(public
) ### 继承 继承可以访问继承的成员变量
,成员方法
,interface
(就是member data,member function中public的部分)
子类可以使用父类的所有内容(但是在实例化的时候就不可以了,实例化的时候只可以访问public的部分!!!!!
) protected属性表示只可以子类访问,其他的类都不行(测试实例化的对象可不可以) private 子类可以访问,但是实例化对象不可以. public 谁都可以访问.
"iostream"
#include
using namespace std;
class Person{
public:
string name;
void work(){
<< "work......" << name << endl;
cout }
Person():name("tom"){};
~Person(){ cout << "~person" << endl;};
private:
int age=10;
void wash_clothes(){
<< "wash clothes" << endl;
cout }
protected:
string book="TomAndJerry";
void use_note(){
<< "use note" << endl;
cout }
};
class Parent :public Person{
string self_book;
public:
void hello(){
= Person::book;// child class can use prarent class protected data;
self_book << self_book << endl;
cout }
void self_wash(){
//Person::wash_clothes();// protected can not use anywhere
}
};
int main(){
;
Parent father<< father.name <<endl;
cout .work();// because is public
father.hello();
father//father.self_book;// protected can be used by class not entertiy
//father.age;// can not be use the reason is not public
return 0;
}
函数重载(function overload)
相同的函数名,接受不同的参数
void hello(){};
void hello(string name){};
void hello(int age){};
void hello(int age,float weight){};
void hello(float height,float wieight){};
...
默认参数(default arguement)
虽然方便但是不推荐,因为在后期调用的时候只能看到赋值一个参数,容易误解
默认参数要写到.h
文件中 a.h
void hello(int i; int j=10);
a.cpp
"a.h"
#include "iostream"
#include
using namespace std;
void hello(int i,int j){
<< i << "|" << j << endl;
cout }
int main(){
hello(999);
return 0;
}
内联函数(inline function)
空间换时间 类型校验 递归问题
,函数代码超过20行
函数构造的的时候直接写操作,默认是inline
的 ### 什么时候inline 代码很少 2~3行 频繁调用(循环中) ### class的inline写法:
# static
// main 函数运行完才会释放
static int a=0;
// 函数执行完就会释放
void func(){
int a = 0;
}
define
define和const的区别
const可以进行类型检查
int A 200; cosnt
define是完全的替换
#define A 100;
const
const 常量,不可以修改.
const double PI=3.1415926
// not allow
++; PI
extern表示这是一个声明而不是一个定义. (有但是不知道是多少,相当于匿名) 告诉编译器说,你可以放心大胆的用,后边我会给你提供值得的 ### 问题 初始化的的时候一定要给具体的值,不可以用extern
extern const int buffersize;
const pointer / pointer const
对象是const: 对象不可以修改.指针可以修改
"iostream"
#include
using namespace std;
class A{
public:
int age=19;
};
int main(){
;
A a;
A a2const A* p1=&a;
<< p1->age=10 <<endl;// error!!!!
cout ++;//not error!!!!
p1return 0;
}
指针是const: 指针不可以修改(不可以p++
)但是可以通过不同的指针
"iostream"
#include
using namespace std;
class A{
public:
int age=19;
};
int main(){
;
A a;
A a2* const p1=&a;
A<< p1->age <<endl;
cout ++; // error!!!!!
p1return 0;
}
p1("tom",18);
Person
const Person* p = &p1; // 对象是const不可以修改
const* p = &p1; // 对象是const不可以修改
Person *const p = &p1; // 指针是const不可以修改
Person const Person *const p = &p1; // 都不可以修改
const写在 * 的前面对象是const
表示指向的那块内存是const,不能通过这个指针修改所指的对象. const写在 * 的后面指针是const
表示指针的地址是const ### 字符类型是放在全局数据区里面的
void hello() const; // 表示这个const加在this上
void hello(cosnt *A this){};
void hello(); // 这两个方法构成了重载.
void hello(*A this){};
引用
<iostream>
#include
int main(){
int a = 100;
int& b = a; // b的vule就是a的value
::cout<< b <<std::endl;
std
return 0;
}
文件保存
<iostream>
#include <fstream>
#include
::ofstream fileSteam;
stdint data = 100;
.open("D:test.txt")
fileSteam
<< data << std::endl;
fileSteam .close() fileSteam
文件读取(按行)
<iostream>
#include <fstream>
#include
int main(){
::string read_data;
std::ifstream inFile("./readme",std::ios::in);
stdwhile(std::getline(inFile,read_data)){
::cout << read_data << std::endl;
std}
.close();
inFilereturn 0;
}