C++

//函数模板
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 object
pb->f(3.14f); // Derived::f(float) 3.14
pd->f(3.14f); // Derived::f(float) 3.14
// Bad : behavior depends on type of the pointer
pb->g(3.14f); // Base::g(float) 3.14
pd->g(3.14f); // Derived::g(int) 3 (surprise!)
// Bad : behavior depends on type of the pointer
pb->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 &); ...
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值