Перейти к содержанию

Последнее обновление:2026-10-12

C++ объявления using и псевдонимы

Об авторе:

Личный официальный аккаунт:

wechat

Основное использование

Локальный и глобальный using; конкретные операции и применение см. в примерах ниже:

#include <iostream>
#define isNs1 1
//#define isGlobal 2
using namespace std;
void func() 
{
    cout<<"::func"<<endl;
}

namespace ns1 {
    void func()
    {
        cout<<"ns1::func"<<endl; 
    }
}

namespace ns2 {
#ifdef isNs1 
    using ns1::func;    /// ns1中的函数
#elif isGlobal
    using ::func; /// 全局中的函数
#else
    void func() 
    {
        cout<<"other::func"<<endl; 
    }
#endif
}

int main() 
{
    /**
     * 这就是为什么在c++中使用了cmath而不是math.h头文件
     */
    ns2::func(); // 会根据当前环境定义宏的不同来调用不同命名空间下的func()函数
    return 0;
}
Полный код см. в: using_global.cpp

Изменение доступности

class Base{
public:
 std::size_t size() const { return n;  }
protected:
 std::size_t n;
};
class Derived : private Base {
public:
 using Base::size;
protected:
 using Base::n;
};

Класс Derived приватно наследует Base: для него переменная-член n и членская функция size являются приватными; если же использовать оператор using, можно изменить их доступность — как в приведённом примере: size доступна с правами public, а n — с правами protected. Полный код см. в: derived_base.cpp

Перегрузка функций

В процессе наследования производный класс может скрыть ноль или более экземпляров перегруженных функций; как только определена одна перегруженная версия, все остальные перегруженные версии становятся невидимыми.

Если для перегруженных функций базового класса нам нужно изменить в производном классе одну из них, оставив остальные видимыми, придётся перегрузить все версии, что весьма трудоёмко.

#include <iostream>
using namespace std;

class Base{
    public:
        void f(){ cout<<"f()"<<endl;
        }
        void f(int n){
            cout<<"Base::f(int)"<<endl;
        }
};

class Derived : private Base {
    public:
        using Base::f;
        void f(int n){
            cout<<"Derived::f(int)"<<endl;
        }
};

int main()
{
    Base b;
    Derived d;
    d.f();
    d.f(1);
    return 0;
}
В приведённом коде в производном классе оператором using-declaration указывается только имя без списка формальных параметров, поэтому одно using-объявление членской функции базового класса добавляет в область видимости производного класса все перегруженные экземпляры этой функции. В этом случае производному классу достаточно определить лишь свои специфические функции, не переопределяя заново остальные унаследованные.

Полный код см. в: using_derived.cpp

Замена typedef

В C часто используется синтаксис typedef A B, определяющий B как тип A, то есть дающий типу A псевдоним B.

Вместо typedef A B для той же операции можно использовать using B=A.

typedef vector<int> V1; 
using V2 = vector<int>;
Полный код см. в: using_typedef.cpp

Похожие темы

Комментарии