C++学习笔记(一)

从C到C++

1.C++的编译过程

编译工具:g++。
步骤:
1.预处理:处理带#号的东西:头文件,宏定义,选择编译
g++ -E *.c -o demo.i
2.编译:语法错误检查
g++ -S *.i -o demo.s
3汇编:将汇编语言转化为二进制语言,生成不可运行的二进制文件。
g++ -c *.s -o demo.o
4链接:将库代码、启动代码 加载到目标文件成为最终的执行程序。
g++ *.o -o demo

2.面向过程和面向对象

1.面向过程:c
面向过程设计:
程序 = 数据结构 + 算法

2.面向对象:c++
面向对象设计:
对象 = 数据结构 + 算法
程序 = (对象 + 对象 + …)+ 对象间通讯机制

3.c和c++的差异具体表现

1.常变量

1.在变量的基础上加const限定: 存储单元中的值不允许变化。因此常变量又称为只读变量(read-only-variable)。
2.注意: const 可以修饰类方法,表示方法不能 修改 类对象

  1. ```c++
     eg:
     	void  primsg()  const  //表示 primsg 是const 修饰的方法 ,不能修改类对象
     	{	
     	}
   ```2. 注意区别用#define命令定义的符号常量和用const定义的常变量

2.强制类型转换

C语言强制类型转换的一般形式:(类型名)(表达式)
示例:(double)a (将a转换成double类型)
C++还增加了以下形式: 类型名(表达式)
示例: int(x); int (x+y);

3.变量的引用

对一个数据可以使用“引用”,这是C++对C的一个重要扩充,引用是一种新的变量类型,它的作用是为一个变量起一个别名。
不能同时引用两个变量
int a=6;
int b=7;
int &c = a;
int &c = b; //不可以
C中函数之间的参数传递方式有:值传递方式、地址传递方式;C++增加了函数参数引用。

4.函数重载

C++允许用同一函数名定义多个函数,这些函数的参数个数和参数类型不同。这就是函数的重载(function overloading)。即对一个函数名重新赋予它新的含义,使一个函数名可以多用。
例如:

   int fun( int x)
   {
   }
   int  fun(int x, int y)
   {
   }
   double fun(int x, int y, double z)
   {
   }

5.结构体

C++语法中相对C语法增加了访问权限的概念,有三种:public、private及protected,默认是public。
public:公共成员,表示可以通过结构体变量对象直接访问到成员
private :私有成员,表示仅结构体成员函数可以使用的成员
protected:保护成员,表示被继承的派生对象可以访问使用的成员
由于增加访问权限,结构体变量就得增加构造函数的概念和this指针,不然成员函数访问成员数据就是问题。

//定义结构体
struct demo{
public:  //公有访问权限:表示结构体内外部 都可以通过 结构体变量访问 
    int  getx() //成员方法 
    {
        return x; 
    }
    void setx(int val) // 成员方法
    {
        x = val; 
    }
    void sety(int val) // 成员方法
    {
        y = val; 
    }
    int  y ;  //公有成员 y  
protected:  //保护访问权限  由 派生的对象 可以访问
private:  //私有 访问权限 只能结构体 内部访问(成员方法)
    int x; 
};
int main()
{
    struct demo obj; 
   // obj.x = 123; // error:x 是 private成员, 不可以通过 外部 变量访问 只能通过 内部访问
    obj.setx(666); 
    printf("%d\n", obj.getx());
    //printf("%d\n", obj.x) ;  //不允许 直接访问 私有成员 x 
    obj.sety(777) ;
    printf("%d\n", obj.y);  //允许直接访问 公有成员 y  
    return 0;
}

6.名字空间

声明:namespace 空间名
使用名字空间:
1.using namespace 空间名;
2. 空间名::prnmsg();

7.动态内存

c:
malloc free :函数
c++
new delete : 运算符
int * p = new int ; delete p
chat *p = new char [1024]; delete [] p

8.标准输入输出流

1.标准输出流
#include
using namespace std;
cout:
cout << 表达式<<表达式2<< … << endl;
2.标准输入流
#include
using namespace std;
cin:
cin>>变量1>>变量2>>…

4.类和对象

1.OPP思想

三个基本特征:
封装:使代码模块化
继承:扩展已经存在的代码模块(类)为了让代码重用
多态:实现接口的重用

2.类和对象

类是对象的抽象,而对象是类的具体实例(instance)。
类是抽象的,不占用内存,而对象是具体的,占用存储空间。在一开始时弄清对象和类的关系是十分重要的。

1.定义类 class
class 类名
{ 
private:
私有的数据和成员函数;
public:
公用的数据和成员函数;
protected:
保护的数据和成员函数
};
2.构造函数和析构函数

1)构造函数
是一种特殊的成员函数,与其他成员函数不同:
A、不需要用户来调用它也不能调用,而是在建立对象时自动执行。
B、构造函数的名字必须与类名同名,而不能由用户任意命名,以便编译系统能识别它并把它作为构造函数处理。
C、没有返回值。
D、构造函数的功能是由用户定义的,用户根据初始化的要求设计函数体和函数参数。
E、如果用户不设计,则编译器自动生成一个。
2> 构造函数声明一般格式为:
构造函数名(类型 1 形参1,类型2 形参2,…)
3> 定义对象的一般格式为 :
类名 对象名(实参1,实参2,…)

2)析构函数
是在一个对象的生命期即将结束的时候,应该回收该对象占有的资源,或是完成一些清理工作。
析构函数既没有返回值,也没有函数参数,因此它不能被重载。
析构函数的语法一般是在类名前加一个“~“。
当对象消亡的时候析构函数会自动被调用。
可以显示调用析构函数。
一般的,不需要进行析构函数显示调用,也会有特殊需求:譬如对象是静态的时候,存在堆区分配,
当程序未结束时候,需要释放堆,这个时候就可以显式调用析构函数来完成。
如果显示调用了析构函数,此时析构函数和普通成员函数是一样的,并不会造成对象被销毁。

#include <iostream>
using namespace std;
class Demo{
public:
    Demo(int val)  //构造函数:无返回值 与类名 同名 可以有形参 :定义对象时,系统自动调用构造函数
    {
        myval = val;   // 
        cout << __func__ << __LINE__<<endl;  //   __func__ :打印当前函数名 __LINE__ 行号 
    }
    ~Demo()  //析构函数:无返回值 无参数  (默认隐式调用)可显示调用,显示调用后  和普通成员函数一样 不会导致对象消亡 
    {
        cout << __func__ << __LINE__<<endl; 
    }
public:
    int getval()
    {
        return myval;
    }

private:
   int myval; 
};

Demo obj2(123); 

int main()
{
   #if 0
    Demo obj(666); //构造对象 并给 构造函数 传参 (实例化 obj对象 )
    cout << obj.getval() << endl; 
#else 
     //static Demo obj3(555);   //静态修饰的局部变量 延长局部对象的生命周期 短于 真正的全局对象
    Demo obj(666);
    cout << obj.getval() << endl; 
    Demo *p = new Demo(777);  //在堆区 给对象 开辟空间 并 构造 
    cout << p->getval() << endl; 
    delete p;  //回收 堆区 空间 
#endif 
    return 0;
}

构造顺序: 谁先执行 就先构造 obj2 obj p
析构顺序: 谁先销毁 谁析构 p obj obj2

3.拷贝构造(浅拷贝和深拷贝)

拷贝构造是一种 特殊的构造函数。 copy constructor。
函数名同 类名 无返回值。
参数形式是固定的。

三种情况:
class Demo{

}
1、一般格式
Demo a;
Demo b(a);  // Demo b = a;

2、动态的创建对象
Demo a;
Demo *p  = new Demo(a);

3、函数传值调用
void test(Demo obj)  
{
cout << obj.show() << endl;
}

注意: 一般 拷贝构造是 不会显示调用 ,而是由编译器隐式调用

重点注意:
区分构造和赋值:
构造:
Demo a(1,2);
Demo b(a); //在创建b 对象的时候 通过 会隐式调用拷贝构造 对b对象初始化
赋值:
Demo a(2,4); 
Demo b;
b = a;  //赋值,不是拷贝构造。

浅拷贝:
只是将成员变量的值 拷贝给 另一个对象
深拷贝:
如果对象的指针成员变量 指向堆区空间, 在拷贝的时候 要开辟新的空间给新对象

this指针是一个特殊的指针,指向类对象自身的首地址。
每个类对象的成员函数都一个this指针,指向调用对象,如果要引用整个对象则*this。
this指针仅能在类内部使用。

#include <iostream>
#include <assert.h>

using namespace std;
class Demo{
public:
    Demo (int len)
    {
        num = len; 
        p = new char [num];
        assert(NULL != p); // 
        for(int i=0; i<num; i++)
        {
            p[i] = i; 
        }
        cout << "line:" << __LINE__ <<endl; 
    }
    #if 0
    Demo (Demo &obj)  //没有重新开辟空间   浅拷贝
    {
        this->num =  obj.num;
        this->p   = obj.p;
        for(int i=0; i<num; i++)
        {
            this->p[i] = obj.p[i];  // 把obj对象里面的数组 数据 拷贝到  this->p  
        }
    }
    #else 
    Demo (Demo &obj)  //重新开辟空间    深拷贝 
    {
        this->num =  obj.num;
        this->p = new char [num];  //重新开辟空间
        assert(NULL != p);  //
        for(int i=0; i<num; i++)
        {
            this->p[i] = obj.p[i];  // 把obj对象里面的数组 数据 拷贝到  this->p  
        }
    }
    #endif 
    ~Demo()
    {
    }
private:
    char *p;
    int num;
};
int main()
{
    Demo obj(10);  
    Demo obj2(obj); // 拷贝构造  拷贝的是数组 
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值