C++

来源:互联网 发布:mac自动刷新功能 编辑:程序博客网 时间:2024/06/06 16:34

//函数模板template <typename T>int compare(T &v1,  T&v2) {}

引用      http://www.cnblogs.com/Mr-xu/archive/2012/08/07/2626973.html

0.基本特性

int a;int &ra = a;  // 引用必须初始化,它只是某个变量的别名(没有自己的存储空间)ra = 1;       // 对引用的修改就是对原变量的修改

1.引用作为参数

    目的:避免参数值拷贝,提高效率。

2.引用作为返回值

    目的:避免拷贝;返回同一个变量,有利于做链式操作。            

    场景:返回值做为左值时必须用引用;  count << "hello" << end; // 流操作符 赋值操作

    注意:

        1.局部变量不能做为引用返回(变量的生命周期已经结束)

        2.不要返回函数内的new分配的内存的引用,申请的内存不好释放。

int &func(const String &rb); // 引用做为形参,函数体中对形参的修改就是对外部调用的实参的修改。没有拷贝一份实参,提高了效率

操作符重载   http://www.cnblogs.com/xiangxiaodong/archive/2012/02/12/2348144.html

class Person{    private:        int age;    public:        Person(int a) {age = a;}    bool  <span style="color:#ff0000;"><strong>operater==</strong></span> (const Person &rb); // 定义}// 做为类的成员函数来实现bool Person::operator== const Person &rb{    if (<span style="color:#ff0000;">this</span>.age == rb.age) return true;    return false;}// 非成员函数的实现bool operator== (Person &<span style="color:#ff0000;">ra</span>, Person &rb){    if (<span style="color:#ff0000;">ra</span>.age == rb.age) return true;    return false;}// 使用Person a(10);Person b(20);if (a == b) ;  // a对象调用比较运算,b做为参数

virtual虚函数

0.目的:

    子类覆盖父类的方法。

            所以:关键字在对象环境中才有意义

    虚函数是运行时确定的。

            因此:静态成员函数(针对一个类非对象),构造函数(对象还没有生成),内联函数(编译期间确定) 都不能声明为virtual的。

1.实现:

    父类中被覆盖的方法前面加此关键字。子类该方法默认带这个关键字。

            表面子类继承了父类的函数,但要重写override它(函数定义一模一样,允许返回值不同)。

2.注意:

    基类的指针调用函数,有virtual的调用子类的函数,否则调用基类的函数。 

    用子类的指针调用,一律调用子类的函数。

    //根据不同子类构造的基类指针,调用相应子类的方法,称为多态。虚函数通过指针或者引用来实现多态。

    virtual void foo()=0; // 纯虚函数,拥有它的类为抽象类,提供了多态的接口。

#include <iostream.h>class Base{public:virtual void f(float x){ cout << "Base::f(float) " << x << endl; }void g(float x){ cout << "Base::g(float) " << x << endl; }void h(float x){ cout << "Base::h(float) " << x << endl; }}; class Derived : public Base{public:virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }void g(int x){ cout << "Derived::g(int) " << x << endl; }void h(float x){ cout << "Derived::h(float) " << x << endl; }}; void main(void){Derived d;Base *pb = &d;Derived *pd = &d;// Good : behavior depends solely on type of the objectpb->f(3.14f); // Derived::f(float) 3.14pd->f(3.14f); // Derived::f(float) 3.14// Bad : behavior depends on type of the pointerpb->g(3.14f); // Base::g(float) 3.14pd->g(3.14f); // Derived::g(int) 3 (surprise!)// Bad : behavior depends on type of the pointerpb->h(3.14f); // Base::h(float) 3.14 (surprise!)pd->h(3.14f); // Derived::h(float) 3.14}


函数的重载

0.目的:

    根据参数的区别来调用同一类函数。

1.实现:

   在一个类中实现几个函数名相同,参数不同的函数。


指针

1. 利用形参修改指针的值

void GetMemory2(char **p, int num){    *p = (char *)malloc(sizeof(char) * num);}
void Test(void){    char *str=NULL;    GetMemory(&str, 100);    strcpy(str,"hello world");    printf(str);}




C++空类默认的成员函数

class Empty{public:    Empty(); // 缺省构造函数    Empty( const Empty& ); // 拷贝构造函数    ~Empty(); // 析构函数    Empty& operator=( const Empty& ); // 赋值运算符    Empty* operator&(); // 取址运算符    const Empty* operator&() const; // 取址运算符 const};

String类的实现

class String{   public:    String(const char *str = NULL); // 普通构造函数    String(const String &other); // 拷贝构造函数    ~ String(void); // 析构函数    String & operate =(const String &other); // 赋值函数   private:    char *m_data; // 用于保存字符串 };//普通构造函数String::String(const char *str) {  if(str==NULL)   {   m_data = new char[1]; // 得分点:对空字符串自动申请存放结束标志'\0'的空  //加分点:对m_data加NULL 判断   *m_data = '\0';   }   else  {   int length = strlen(str);    m_data = new char[length+1]; // 若能加 NULL 判断则更好    strcpy(m_data, str);   }}// String的析构函数String::~String(void) {  delete [] m_data; // 或delete m_data;}//拷贝构造函数String::String(const String &other)    // 得分点:输入参数为const型{   int length = strlen(other.m_data);   m_data = new char[length+1];     //加分点:对m_data加NULL 判断  strcpy(m_data, other.m_data); }//赋值函数String & String::operate =(const String &other) // 得分点:输入参数为const型{   if(this == &other)   //得分点:检查自赋值   return *this;   delete [] m_data;     //得分点:释放原有的内存资源  int length = strlen( other.m_data );   m_data = new char[length+1];  //加分点:对m_data加NULL 判断  strcpy( m_data, other.m_data );   return *this;         //得分点:返回本对象的引用} 



const

1. 修饰为常量

A const int* a = &b; //指针指向的是常量,但指针可变。 B const* int a = &b; //指针是常量,指向的值可变C const int* const a = &b; //a和*a都是const,常量和指针的值都不能改变D int const* const a = &b; //a和*a都是const,常量和指针的值都不能改变


static


extern

sizeof()的用法

sizeof操作符的结果类型是size_t,它在头文件 中typedef为unsigned int类型。

1. sizeof(p) = 4; // 指针的大小为4字节,数组做参数时沦为指针类型,其大小为4.2. char str[] = "abcd";  // sizeof(str) = 5, 得到静态数组的大小,包括字串结束符;区别:strlen(str)=4;求字串的大小,不包括结束符。


对齐

目的:提高CPU存储变量的速度

实现:

1.系统默认对齐  ==  每个变量的偏倚地址是此变量大小的倍数  &&  总空间大小是最大变量大小的倍数

struct MyStruct {     char dda;  //偏移量为0,满足对齐方式,dda占用1个字节;     double dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8 的倍数,VC需要补足7个字节满足对齐方式,dda1存放在偏移量为8的地址上,它占用8个字节。     int type;//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍数,满足int的对齐方式,所以不需要VC自动填充,type存放在偏移量为16的地址上,它占用4个字节 };//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构 //的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以需要填充4个字节。所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。  

2.自定义对齐

      n字节对齐 == 变量存放的起始地址的偏移量为min(n, 默认值)

#pragma pack(push)   //保存对齐状态 #pragma pack(4)      //设定为4字节对齐 struct test { char m1; double m4; int m3; }; #pragma pack(pop)//恢复对齐状态 以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为 m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。


数组

1. 数组的大小要求为编译期间常量

unsigned int temp = 3;unsigned int const size = temp;char str[ size ];  // 编译错误,运行时才知道数组的大小。如果unsigned int const size = 3; char str[size]; 这样定义OK。

int id[sizeof(unsigned long)];  // 这个对。sizeof是编译时运算符,编译时就确定了可以看成和机器有关的常量。



与零比较
BOOL型变量:if(!var)int型变量: if(var==0)float型变量:const float EPSINON = 0.00001;   if ((x >= - EPSINON) && (x <= EPSINON)指针变量: if(var==NULL)


模板

1.函数模板

template <typename T>int compare(T &v1, T&v2) {...}
2.类模板  eg. vector, map
template <class Type>class myQueue:Queue<Type>{public:    void push(const Type &); ...}


0 0
原创粉丝点击