C++ Primer 学习笔记 第十九章 特殊工具与技术

本文探讨了C++中的内存管理技术,包括自定义new和delete操作符、显式析构函数调用、dynamic_cast的使用及RTTI类型识别等功能。此外,还介绍了枚举类型、数据成员指针的应用、函数成员的使用、通过函数表实现多态行为的方法,以及如何将string成员函数转换为可调用对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

728

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


void *operator new(size_t size){
    if(void *mem= malloc(size)){
        return mem;
    } else{
        throw bad_alloc();
    }
}

void operator delete(void *mem) noexcept{
    free(mem);
}

int main(int argc,char** argv){
    string *sp = new string("dfs");
    delete sp;

    return 0;
}

19.1

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


void *operator new(std::size_t n){
    cout << "new(size_t)" << endl;
    if (void *mem= malloc(n))
        return mem;
    else
        throw bad_alloc();
}

void operator delete(void *mem) noexcept{
    cout << "delete(void*)" << endl;
    free(mem);
}


int main(int argc,char** argv){
    using namespace std;
    int *a = new int(486);
    cout << a << " " << *a << endl;
    delete a;
    return 0;
}

729 显式的析构函数调用

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;



int main(int argc,char** argv){
    string *sp = new string("a value");
    sp->~string();

    return 0;
}

731 dynamic_cast运算符

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Base{
public:
    virtual void fuc(){};

};

class Derived:public Base{
public:


};



int main(int argc,char** argv){

    Base *bp = new Derived;

    if (Derived *p = dynamic_cast<Derived*>(bp)){
        cout << "Base* -> Derived*" << endl;
    } else{
        cout << "error" << endl;
    }

    Derived d;
    const Base &b1 = d;
    const Derived &d1 = dynamic_cast<const Derived&>(b1);

    return 0;
}


19.5

    A *pa = new C;
    C &c = dynamic_cast<C&>(*pa);

733 使用RTTI

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Base{
    friend bool operator=(const Base&, const Base&);

public:
protected:
    virtual bool equal(const Base&) const;
};

class Derived:public Base{
public:
protected:
    bool equal(const Base&) const;
};

bool operator==(const Base &lhs, const Base &rhs){
    return typeid(lhs)==typeid(rhs) && lhs.equal(rhs);
}


int main(int argc,char** argv){
    Derived *dp = new Derived;
    Base *bp = dp;

    if (typeid(*bp)== typeid(*dp)){
        cout << "*bp == *dp" << endl; // *bp == *dp
    }
    if (typeid(*bp) == typeid(Derived)){
        cout << "*bp==Derived" << endl; // "*bp==Derived"
    }



    return 0;
}


735

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Base{
    friend bool operator=(const Base&, const Base&);

public:
protected:
    virtual bool equal(const Base&) const;
};

class Derived:public Base{
public:
protected:
    bool equal(const Base&) const;
};

bool operator==(const Base &lhs, const Base &rhs){
    return typeid(lhs)==typeid(rhs) && lhs.equal(rhs);
}

bool Derived::equal(const Base &rhs) const {
    auto r = dynamic_cast<const Derived&>(rhs);
}

bool Base::equal(const Base &rhs) const {

}



int main(int argc,char** argv){
    Derived *dp = new Derived;
    Base *bp = dp;

    if (typeid(*bp)== typeid(*dp)){
        cout << "*bp == *dp" << endl; // *bp == *dp
    }
    if (typeid(*bp) == typeid(Derived)){
        cout << "*bp==Derived" << endl; // "*bp==Derived"
    }



    return 0;
}

typeid使用方法

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;

class Derived{

};


int main(int argc,char** argv){
    int arr[10];
    cout << typeid(42).name() <<endl; // int

    Derived d;
    cout << typeid(d).name() << endl; // class Derived

    return 0;
}


typeid

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;

class Derived{

};


int main(int argc,char** argv){
    int arr[10];
    cout << typeid(42).name() <<endl; // int

    Derived d;
    cout << typeid(d).name() << endl; // class Derived


    return 0;
}


738 枚举类型

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


int main(int argc,char** argv){
    enum color {red='a', yellow, green};
    // enum stoplight {red, yellow, green}; error redefinition
    enum class peppers {red, yellow, green};
    color eyes = green;
    cout << typeid(eyes).name() << endl;
    color hair = color::red;
    peppers p2 = peppers::red;
    cout << typeid(peppers).name() << endl;

    enum class intTypes{
        charTyp=8, shortTyp=16, intTyp=16,
        longTyp=32, long_longTyp=64
    };

    constexpr intTypes charbits = intTypes::charTyp;
//    open_modes om = 2;
//    om = open_modes::inputs;
    int j = color::red;
    cout << j << endl; // 97 a的ASCII码

    // 指定enum的大小
    enum intValues:unsigned long long{
        charTyp=255, shortTyp=63335
    };

    enum class intValues1:int;
//    enum intValues1:long;




    return 0;
}


739

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


enum Tokens {INLINE=128, VIRTUAL=129};
void ff(Tokens);
void ff(int);

void newf(unsigned char c){
    cout << c << endl;
};
void newf(int);



int main(int argc,char** argv){
    Tokens curTok = INLINE;
    ff(128);
    ff(INLINE);
    ff(curTok);

    unsigned char uc = VIRTUAL;
//    newf(VIRTUAL);
    newf(uc);
    return 0;
}


740 数据成员指针

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Screen{
public:
    typedef std:: string::size_type pos;
    char get_cursor() const {return contents[cursor];}
    char get() const;
    char get(pos ht, pos wd) const;

    std::string contents;
    pos cursor;
    pos height, width;
    
};


int main(int argc,char** argv){
    // screen类指针
    const Screen* pi;
    // 指向screen类string成员
    const string Screen::*pdata;
    pdata = &Screen::contents;
    // 等价于上面
    auto pdata1 = &Screen::contents;

    Screen myScreen, *pScreen = &myScreen;
    // 解引用获得成员
    auto s = myScreen.*pdata;
    s = pScreen->*pdata;
    return 0;
}


741 使用一个成员函数来外露类里面的数据

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Screen{
public:
    typedef std:: string::size_type pos;
    char get_cursor() const {return contents[cursor];}
    char get() const;
    char get(pos ht, pos wd) const;

    static const std::string Screen::*data(){
        return &Screen::contents;
    };

private:
    std::string contents = "hello";
    pos cursor;
    pos height, width;

};


int main(int argc,char** argv){
    Screen s;
    const string Screen::*data = Screen::data();
    cout << s.*data << endl;
    
    return 0;
}


743 函数成员

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Screen{
public:
    typedef std:: string::size_type pos;
    char get_cursor() const {return contents[cursor];}
    char get() const;
    char get(pos ht, pos wd) const{
        return 'l';
    };
    static const std::string Screen::*data(){
        return &Screen::contents;
    };

private:
    std::string contents = "hello";
    pos cursor;
    pos height, width;

};

using Action = char (Screen::*)(Screen::pos, Screen::pos) const;

Screen& action(Screen& s, Action=&Screen::get){
    return s;
}

int main(int argc,char** argv){
    // 定义
    char (Screen::*pmf2)(Screen::pos, Screen::pos) const;
    pmf2 = &Screen::get;
    // 调用
    Screen myScreen, *pScreen = &myScreen;
    char c1 = (pScreen->*pmf2)(1,  2);
    cout << c1 << endl;
    
    
    Action get = &Screen::get;
    
    action(myScreen);
    action(myScreen, get);
    action(myScreen, &Screen::get);

    return 0;
    
}


744 函数表

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Screen{
public:
    using Action = Screen& (Screen::*)();
    enum Directions {HOME, FORWARD, BACK, UP, DOWN};
    Screen& move(Directions);
    Screen& home();
    Screen& forward();
    Screen& back();
    Screen& up(){
        cout <<"up" << endl;
        return this->down();
    };
    Screen& down();

private:
    static Action Menu[];
};

// 函数表
Screen::Action Screen::Menu[] = {
        &Screen::home,
        &Screen::forward,
        &Screen::back,
        &Screen::up,
        &Screen::down,
};

Screen& Screen::move(Directions cm) {
    return (this->*Menu[cm])();
}



int main(int argc,char** argv){
    Screen myScreen;
    myScreen.move(Screen::UP);
    return 0;
}

746 将string的成员函数转换成可调用对象

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;




int main(int argc,char** argv){
    auto f = mem_fn(&string::empty);
    string s = "";
    cout << f(s) << endl; // 1

    auto f2 = bind(&string::empty, placeholders::_1);
    cout << f2(s) << endl; // 1

    
    return 0;

}

749 union的定义与赋值

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


union Token{
    char cval;
    int ival;
    double dval;
};


int main(int argc,char** argv){

    Token first_token = {'a'};
    Token last_token;
    Token *pt = new Token;

    last_token.cval = 'z';
    last_token.ival = 'a';
    pt->ival = 42;


    return 0;

}

匿名的union

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;




int main(int argc,char** argv){
    union {
        char cval;
        int ival;
        double dval;
    };

    cval = 'z';
    ival = 'a';
    ival = 42;
    cout << ival << endl;


    return 0;

}

753 使用类管理union

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


class Token{
public:
    Token():tok(INT), ival(0) {}
    Token(const Token &t):tok(t.tok){copyUnion(t);}
    Token &operator=(const Token&);
    ~Token(){if (tok==STR) sval.~string();}
    Token &operator=(const std::string&);
    Token &operator=(char);
    Token &operator=(int);
    Token &operator=(double);
private:
    enum {INT, CHAR, DBL, STR} tok;
    union {
        char cval;
        int ival;
        double dval;
        std::string sval;
    };
    void copyUnion(const Token&);
};


Token &Token::operator=(int i) {
    if (tok==STR) sval.~string();
    ival = i;
    tok = INT;
    return *this;
}

Token &Token::operator=(double d) {
    if (tok==STR) sval.~string();
    dval = d;
    tok = DBL;
    return *this;
}


Token &Token::operator=(char c){
    if (tok==STR) sval.~string();
    cval = c;
    tok = CHAR;
    return *this;
}

Token &Token::operator=(const std::string &s) {
    if (tok==STR)
        sval = s;
    else
        new(&sval) string(s);
    tok = STR;
    return *this;
}

void Token::copyUnion(const Token &t) {
    switch (t.tok){
        case Token::INT:ival=t.ival; break;
        case Token::CHAR:cval=t.cval; break;
        case Token::DBL:dval=t.dval; break;
        case Token::STR:new(&sval) string(t.sval); break;
    }
}

Token &Token::operator=(const Token &t) {
    if (tok==STR && t.tok!=STR) sval.~string();
    if (tok==STR && t.tok==STR)
        sval = t.sval;
    else
        copyUnion(t);
    tok = t.tok;
    return *this;
}



int main(int argc,char** argv){

    Token t1, t2;
    t1 = "hello";
    t2 = t1;
    Token t3(t1);
    return 0;

}

局部类

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <iterator>
#include <memory>
#include <fstream>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <bitset>
#include <regex>
#include <random>
#include <ctime>
#include <iomanip>
#include <exception>
using namespace std;


int a, val;
void foo(int val){
    static int si;
    enum Loc{a=1024, b};
    struct Bar{
        Loc locVal;
        int barVal;
        void fooBar(Loc l=a){
//            barVal = val;
            barVal = ::val;
            barVal = si;
            locVal = b;
        }
    };
}


int main(int argc,char** argv){

    foo(32);

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值