• C++ 关键字 explicit, export, mutable


    explicit

    如果A类有某个构造函数的单个输入参数,是B类(包括基本数据类型)的对象或引用,则C++的编译器会在需要A类形参的函数调用中,自动调用该构造函数,将B类实参隐式地转换为A类实参。

    这种自动类型转换的好处是,避免了定义函数的两个重载版本,代价是隐式调用构造函数会增加调用开销,并可能会带来其他问题。

    在标准C++中,新增加了关键字explicit(显式/清楚/明确),(只能)用在带单个参数的构造函数前,告诉编译器,不能使用该构造函数进行隐式类型转换。如果确实想转换,则必须采用显式的类型转换方式来进行。从而避免了可能出现的问题和额外的调用开销。

    例如:

    class One {……};

    class Two {

    public:

           explicit Two (const One& one) {……}

    };

    void f (Two two) {……}

    int main ( ) {

           One one;

           f (one); // 错误(前面代码中无explicit时正确——调用Two(one)进行隐式类型转换)

           f (Two(one)); // 正确——采用了显式类型转换

    }

    export

    为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字extern,来使用这些变量或对象时;但是对模板类型,则必须在定义这些模板类对象和模板函数时,使用标准C++新增加的关键字export(导出/出口/输出)。例如:

    extern int n;

    extern struct Point p;

    extern class A a;

    export template<class T> class Stack<int> s;

    export template<class T> void f (T& t) {……}

    一般是在头文件中给出类的定义或全局函数的声明信息,而在代码文件中给出具体的(类成员函数或全局函数的)函数定义。然后在多个用户代码文件中包含该头文件后,就可以使用其中定义或声明的类和函数。头文件中一般不包含变量、结构和类对象的定义,因为这样可能会导致重复定义的编译错误。解决办法是,在某个代码文件中进行定义,在其他用户代码文件中用extern来引用它们。

    但是对模板类型,则可以在头文件中,声明模板类和模板函数;在代码文件中,使用关键字export来定义具体的模板类对象和模板函数;然后在其他用户代码文件中,包含声明头文件后,就可以使用该这些对象和函数了。例如:

    // out.h:(声明头文件——只包含out函数的声明信息)

    template<class T> void out (const T& t);

    // out.cpp:(定义代码文件——包含out函数的声明[通过include]和定义等全部信息)

    #include <iostream>

    #include “out.h”

    export template<class T> void out (const T& t) {std::cerr << t;}

    //user.cpp:(用户代码文件——包含函数的声明头文件后就可以使用该函数)

    #include “out.h”

    // 使用out()

    说明:VC05目前还不支持export关键字(的编译)。

    mutable

    在类的常型(const)成员函数中,一般是不让改变类中数据成员的。如果想在常型成员函数中改变类的数据成员,在传统C++中,为达到此目,可采用一种奇怪的方式——先将this指针强制转换成一个本类的指针,然后就可以利用该指针来对类的数据成员进行任意的修改。但是,这种修改是隐藏在成员函数内部的,在类定义(头文件)中根本看不出来,而且它也破坏了设置常型成员函数的本意。

    标准C++中新增加了一个关键字mutable(易变/可变/不定/无常的),用在类的数据成员前,明确表示该成员变量可以在常型成员函数中被修改。例如:

    class A

     {

           int i;

           mutable int j;

    public:

           void f ( ) const;

    };

    void A::f ( ) const {

           i++; // 错误——常型成员函数不允许改变数据成员的值

           ((A*)this)->i++; // 可以——已经过时,不被提倡

           j++; // 正确——mutable型成员变量

    }

  • 相关阅读:
    正确添加Google Adsense
    微软开发主管临别诤言
    DZ论坛重建管理员
    Cook book 第4天 第6章 层、自定义组件
    Cook Book 第二天 运行环境识别修改
    flex cookbook 学习第一天 基本知识
    C#:String类型中的CharAt
    对我学C#时的一次小回忆[一:语法篇]
    分享一段C#反射代码[Type是反射的入口][查看类型信息][动态生成对象]
    C#反射:让私有成员无所遁形
  • 原文地址:https://www.cnblogs.com/skyofbitbit/p/3649759.html
Copyright © 2020-2023  润新知