1 -> *运算符重载
//autoptr.cpp
 
 
#include<iostream>
#include<string>
using namespace std;
 
struct date{
    int year;
    int month;
    int day;
};
 
struct Person{
    string name;
    int age;
    bool gender;
    double salary;
    date birthday;
   
    Person() {cout<<"创建Person对象在"<<this<<endl;}
   
    ~Person(){cout<<"释放Person对象在"<<this<<endl;}
};
 
class autoptr{
    Person *p;
    static int cnt;
public:
    autoptr(Person *p):p(p){}
    autoptr(const autoptr& a):p(a.p){++cnt;}
 
   
    ~autoptr(){
        cout<<"cnt="<<autoptr::cnt<<endl;
        if(--cnt==0)
        delete p;
    }
 
    Person* operator->() {return p;}  //将对象模拟成指针
   
    Person& operator*() {return *p;}
};
 
int autoptr::cnt=0;
 
int main()
{
    //autoptr a(new Person());
    autoptr a=new Person();
    autoptr b=a;
    autoptr c=a;
 
    cout<<"=============================="<<endl;
 
    a->name="zhangming";
    cout<<"name:"<<(*a).name<<endl;
 
    a->birthday.year=1993;
    a->birthday.month=10;
    a->birthday.day=9;
    cout<<"birthday:"<<(*a).birthday.year<<"/"<<(*a).birthday.month
        <<"/"<<(*a).birthday.day<<endl;
   
    cout<<"==============================="<<endl;
 
    return 0;
}
 
 
2.赋值运算符=重载,实现堆栈类
//stack.cpp
 
 
#include<iostream>
#include<string>
using namespace std;
 
typedef unsigned int uint;
 
class Stack
{
public:
    Stack(uint n):mem(new string[n]),max(n),len(0){}
    Stack(const Stack &s):mem(new string[s.max]),
                  max(s.max),len(s.len){}
 
    uint max_size()const {return max;} 
    uint size()const {return len;}
 
    Stack& push(const string &s)
    {
        if(len>=max) throw 1;
        mem[len++]=s;
        return *this;
    }
   
    string pop()
    {
        if(len==0) throw 0;
        return mem[--len];
    }
 
    ~Stack(){ delete[]mem; }
 
    void print()const{
        for(int i=0;i<len;i++)
        {
            cout<<mem[i]<<" ";
        }
        cout<<endl;
    }
 
    //重载赋值运算符
    Stack& operator=(const Stack &s)
    {
        if(*this==s)  return *this;  //考虑到自己给自己赋值
 
        delete[]mem; //释放原来的空间
 
        this->mem=new string[s.max];
        this->len=s.len;
        this->max=s.max;
 
        for(int i=0;i<len;i++)
        {
            mem[i]=s.mem[i];
        }
 
        return *this;
    }
 
private:
    string* mem;   
    uint max;
    uint len;
};
 
 
int main()
{
    Stack s1(5);
    Stack s2(s1); //错误,s1与s2同时指向同一块内存,
              //致使delete重复释放,
              //可以使用拷贝构造函数解决
    Stack s3(8);
 
    s1.push("1").push("2").push("3").push("4").push("5");
    s1.print();
 
    s1.pop();
    s1.pop();
   
    s1.print();
 
    s2.push("zhangming").push("wangwu");
    s2.print();
   
    s3=s1;   //s3.operator=(s1)
    s3.print();  //1 2 3
 
    s1=s2;
    s1.print();  //zhangming wangwu
 
    s3=s3;
    s3.print();  //1 2 3
 
    return 0;
}
 
 
 
3.new delete 运算符重载
//ND.cpp
 
#include<iostream>
using namespace std;
 
const int max_size=1000;
int mem[max_size];
 
class A
{
public:
    A(){cout<<"A()"<<endl;}
   
    ~A(){cout<<"~A()"<<endl;}
 
    static void* operator new(size_t bytes)  //bytes=sizeof(A)
    {
        cout<<"new"<<endl;
 
        alloc=bytes;  //即alloc=sizeof(A)
        if(alloc>max_size) throw 0;
 
        return (mem+alloc);
    }
 
    static void operator delete(void *p)
    {
        cout<<"delete"<<endl;
        alloc=0;   
    }
 
    void init(int n){
        memset(mem,max_size,sizeof(int));
        for(int i=0;i<n;i++)
        {
            mem[i]=i;  
        }
    }
 
    void show(){
        for(int i=0;i<alloc;i++)
        {
            cout<<mem[i]<<" "; 
        }
        cout<<endl;
    }
 
private:
    static int alloc;
    int num;
    char name[10];
};
 
int A::alloc=0;
 
int main()
{
    A *a=new A;  //实参实际上为sizeof(A)
 
    a->init(5);  //给分配的前五个元素赋初值,剩余元素赋0
    a->show();
 
    delete a;
 
    return 0;
}
 
 
 
 
4.虚函数与虚表指针
//virtual.cpp
 
 
#include<iostream>
using namespace std;
 
class A{
    int d;
public:
    virtual void f(){cout<<"A类的虚函数"<<endl;}
    virtual void g(){cout<<this<<","<<&d<<endl;}
    int* get_d(){return &d;}
};
 
class B:public A{
    int d;
public:
    void f(){cout<<"B类的虚函数"<<endl;}
    void g(){cout<<this<<","<<get_d()<<endl;}
    void k(){}
    void m(){}
    void n(){} 
};
 
int main()
{
    A *p=new A;
    A *q=new B;
 
    p->f();  //输出:A类的虚函数
    q->f();  //输出:B类的虚函数
   
    p->g();
    q->g();
 
    memcpy(q,p,4);//让q所指对象的虚表指针指向A类
    q->f();  //输出:A类的虚函数
   
    delete p;
    delete q;
 
    cout<<"================="<<endl;
    cout<<sizeof(A)<<endl;
    cout<<sizeof(B)<<endl;
    cout<<"================="<<endl;
 
    return 0;
}

标准C++之运算符重载和虚表指针的更多相关文章

  1. C++_day06_运算符重载_智能指针

    1.只有函数运算符可以带缺省函数,其他运算符函数主要由操作符个数确定 2.解引用运算符和指针运算符 示例代码: #include <iostream> using namespace st ...

  2. C++运算符重载的妙用

    运算符重载(Operator overloading)是C++重要特性之中的一个,本文通过列举标准库中的运算符重载实例,展示运算符重载在C++里的妙用.详细包含重载operator<<,o ...

  3. CPP_运算符重载及友元

    运算符重载 两种重载方法1)成员函数 a + b => a.operator+(b); 一个参数 2)友元函数 a + b => operator+(a, b); 两个参数. friend ...

  4. 新标准C++程序设计读书笔记_运算符重载

    形式 返回值类型 operator 运算符(形参表) { …… } 运算符重载 (1)运算符重载的实质是函数重载(2)可以重载为普通函数,也可以重载为成员函数 class Complex { publ ...

  5. c/c++面试题(6)运算符重载详解

    1.操作符函数: 在特定条件下,编译器有能力把一个由操作数和操作符共同组成的表达式,解释为对 一个全局或成员函数的调用,该全局或成员函数被称为操作符函数.该全局或成员函数 被称为操作符函数.通过定义操 ...

  6. C++学习笔记之运算符重载

    一.运算符重载基本知识 在前面的一篇博文 C++学习笔记之模板(1)——从函数重载到函数模板 中,介绍了函数重载的概念,定义及用法,函数重载(也被称之为函数多态)就是使用户能够定义多个名称相同但特征标 ...

  7. C++:运算符重载函数

    5.运算符重载 5.1 在类外定义的运算符重载函数 C++为运算符重载提供了一种方法,即在运行运算符重载时,必须定义一个运算符重载函数,其名字为operator,后随一个要重载的运算符.例如,要重载& ...

  8. 三道题(关于虚表指针位置/合成64位ID/利用栈实现四则运算)

    第一题 C++标准中,虚表指针在类的内存结构位置没有规定,不同编译器的实现可能是不一样的.请实现一段代码,判断当前编译器把虚表指针放在类的内存结构的最前面还是最后面.  第二题 在游戏中所有物品的实例 ...

  9. [置顶] operator overloading(操作符重载,运算符重载)运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy)

    operator overloading(操作符重载,运算符重载) 所谓重载就是重新赋予新的意义,之前我们已经学过函数重载,函数重载的要求是函数名相同,函数的参数列表不同(个数或者参数类型).操作符重 ...

随机推荐

  1. yii2缓存的介绍和使用

    作者:白狼 出处:http://www.manks.top/yii2_cache.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律 ...

  2. 原生JS 表单提交验证器

    转载:http://www.cnblogs.com/sicd/p/4613628.html 一.前言 最近在开发一个新项目,需要做登陆等一系列的表单提交页面.在经过“缜密”的讨论后,我们决定 不用外部 ...

  3. ORACLE会话连接进程三者总结

    概念介绍 通俗来讲,会话(Session) 是通信双方从开始通信到通信结束期间的一个上下文(Context).这个上下文是一段位于服务器端的内存:记录了本次连接的客户端机器.通过哪个应用程序.哪个用户 ...

  4. Linux SendMail服务启动慢总结

    在 CentOS release 6.6 上启动sendmail服务时发现服务启动过程非常慢,基本上要耗费3分多钟.有点纳闷:什么原因导致sendmail启动这么慢?搜索了这方面的一些资料,结合自己的 ...

  5. SQL SERVER 临时表导致存储过程重编译(recompile)的一些探讨

    SQLSERVER为了确保返回正确的值,或者处于性能上的顾虑,有意不重用缓存在内存里的执行计划,而重新编译执行计划的这种行为,被称为重编译(recompile).那么引发存储过程重编译的条件有哪一些呢 ...

  6. YourSQLDba将数据库置于紧急模式的原因浅析

    从SQL SERVER 2000 上迁移了一个数据库到SQL SERVER 2008 R2上,暂且用DataBaseName代替迁移的真实的数据库名(后面的资料也会将数据库真实的名字用DataBase ...

  7. ORACLE 物理读 逻辑读 一致性读 当前模式读总结浅析

    在ORACLE数据库中有物理读(Physical Reads).逻辑读(Logical Reads).一致性读(Consistant Get).当前模式读(DB Block Gets)等诸多概念,如果 ...

  8. jquery本地上传预览扩展(隐藏上传控件单击图片上传支持ie!!)

    我用到的原材料地址:http://www.cnblogs.com/leejersey/p/3660202.html 修改后: /// <reference path="../../Js ...

  9. SQL2005/2008 无法连接错误

    SQL2005/2008 .或者是localhost可以访问,但是127.0.0.1或者IP无法访问 打开[SQL Server 配置管理器](如果是MSSQL2005,在运行中输入SQLServer ...

  10. HTML基本组成结构与标签的认识

    HTML基本组成结构与标签 其实组成结构用一张图来简单了解下如下 目前一般网站的结构是会如此不是很清晰简单 先来说说header头部 这样是不是更加清楚了 导航栏是引导用户查看网站内容的快捷入口,打个 ...