Bagikan melalui


menggunakan deklarasi

using Deklarasi memperkenalkan nama ke wilayah deklaratif tempat deklarasi penggunaan muncul.

Sintaks

using [typename] nested-name-specifier unqualified-id ;
using declarator-list ;

Parameter

nested-name-specifier Urutan namespace, kelas, atau nama enumerasi dan operator resolusi cakupan (::), dihentikan oleh operator resolusi cakupan. Operator resolusi cakupan tunggal dapat digunakan untuk memperkenalkan nama dari namespace layanan global. Kata kunci typename bersifat opsional dan dapat digunakan untuk mengatasi nama dependen saat dimasukkan ke dalam templat kelas dari kelas dasar.

unqualified-id Ekspresi id yang tidak memenuhi syarat, yang mungkin merupakan pengidentifikasi, nama operator yang kelebihan beban, operator literal yang ditentukan pengguna atau nama fungsi konversi, nama destruktor kelas, atau nama templat dan daftar argumen.

declarator-list Daftar deklarator yang dipisahkan koma dari [typename] deklarator unqualified-id nested-name-specifier, diikuti secara opsional oleh elipsis.

Keterangan

Deklarasi menggunakan memperkenalkan nama yang tidak memenuhi syarat sebagai sinonim untuk entitas yang dideklarasikan di tempat lain. Ini memungkinkan satu nama dari namespace tertentu digunakan tanpa kualifikasi eksplisit di wilayah deklarasi tempat namespace tersebut muncul. Hal ini berbeda dengan direktif penggunaan, yang memungkinkan semua nama dalam namespace untuk digunakan tanpa kualifikasi. Kata using kunci juga digunakan untuk alias jenis.

Contoh: using deklarasi di bidang kelas

Deklarasi menggunakan dapat digunakan dalam definisi kelas.

// using_declaration1.cpp
#include <stdio.h>
class B {
public:
   void f(char) {
      printf_s("In B::f()\n");
   }

   void g(char) {
      printf_s("In B::g()\n");
   }
};

class D : B {
public:
   using B::f;    // B::f(char) is now visible as D::f(char)
   using B::g;    // B::g(char) is now visible as D::g(char)
   void f(int) {
      printf_s("In D::f()\n");
      f('c');     // Invokes B::f(char) instead of recursing
   }

   void g(int) {
      printf_s("In D::g()\n");
      g('c');     // Invokes B::g(char) instead of recursing
   }
};

int main() {
   D myD;
   myD.f(1);
   myD.g('a');
}
In D::f()
In B::f()
In B::g()

Contoh: using deklarasi untuk mendeklarasikan anggota

Ketika digunakan untuk mendeklarasikan anggota, deklarasi penggunaan harus merujuk ke anggota kelas dasar.

// using_declaration2.cpp
#include <stdio.h>

class B {
public:
   void f(char) {
      printf_s("In B::f()\n");
   }

   void g(char) {
      printf_s("In B::g()\n");
   }
};

class C {
public:
   int g();
};

class D2 : public B {
public:
   using B::f;   // ok: B is a base of D2
   // using C::g;   // error: C isn't a base of D2
};

int main() {
   D2 MyD2;
   MyD2.f('a');
}
In B::f()

Contoh: using deklarasi dengan kualifikasi eksplisit

Anggota yang dideklarasikan dengan menggunakan deklarasi menggunakan dapat direferensikan dengan menggunakan kualifikasi eksplisit. :: Awalan mengacu pada namespace global.

// using_declaration3.cpp
#include <stdio.h>

void f() {
   printf_s("In f\n");
}

namespace A {
   void g() {
      printf_s("In A::g\n");
   }
}

namespace X {
   using ::f;   // global f is also visible as X::f
   using A::g;   // A's g is now visible as X::g
}

void h() {
   printf_s("In h\n");
   X::f();   // calls ::f
   X::g();   // calls A::g
}

int main() {
   h();
}
In h
In f
In A::g

Contoh: using sinonim dan alias deklarasi

Ketika deklarasi penggunaan dibuat, sinonim yang dibuat oleh deklarasi hanya mengacu pada definisi yang valid pada titik deklarasi penggunaan. Definisi yang ditambahkan ke namespace setelah deklarasi penggunaan bukan sinonim yang valid.

Nama yang using ditentukan oleh deklarasi adalah alias untuk nama aslinya. Ini tidak memengaruhi jenis, tautan, atau atribut lain dari deklarasi asli.

// post_declaration_namespace_additions.cpp
// compile with: /c
namespace A {
   void f(int) {}
}

using A::f;   // f is a synonym for A::f(int) only

namespace A {
   void f(char) {}
}

void f() {
   f('a');   // refers to A::f(int), even though A::f(char) exists
}

void b() {
   using A::f;   // refers to A::f(int) AND A::f(char)
   f('a');   // calls A::f(char);
}

Contoh: Deklarasi dan using deklarasi lokal

Sehubungan dengan fungsi di namespace layanan, jika sekumpulan deklarasi lokal dan menggunakan deklarasi untuk satu nama diberikan di wilayah deklaratif, semuanya harus merujuk ke entitas yang sama, atau semuanya harus merujuk ke fungsi.

// functions_in_namespaces1.cpp
// C2874 expected
namespace B {
    int i;
    void f(int);
    void f(double);
}

void g() {
    int i;
    using B::i;   // error: i declared twice
    void f(char);
    using B::f;   // ok: each f is a function
}

Dalam contoh di atas, using B::i pernyataan menyebabkan detik int i dideklarasikan dalam g() fungsi. Pernyataan using B::f tidak bertentang f(char) dengan fungsi karena nama fungsi yang diperkenalkan dengan B::f memiliki jenis parameter yang berbeda.

Contoh: Deklarasi dan using deklarasi fungsi lokal

Deklarasi fungsi lokal tidak boleh memiliki nama dan jenis yang sama dengan fungsi yang diperkenalkan dengan menggunakan deklarasi. Contohnya:

// functions_in_namespaces2.cpp
// C2668 expected
namespace B {
    void f(int);
    void f(double);
}

namespace C {
    void f(int);
    void f(double);
    void f(char);
}

void h() {
    using B::f;          // introduces B::f(int) and B::f(double)
    using C::f;          // C::f(int), C::f(double), and C::f(char)
    f('h');              // calls C::f(char)
    f(1);                // C2668 ambiguous: B::f(int) or C::f(int)?
    void f(int);         // C2883 conflicts with B::f(int) and C::f(int)
}

Contoh: using deklarasi dan pewarisan

Sehubungan dengan pewarisan, ketika deklarasi penggunaan memperkenalkan nama dari kelas dasar ke dalam cakupan kelas turunan, fungsi anggota di kelas turunan mengambil alih fungsi anggota virtual dengan nama dan jenis argumen yang sama di kelas dasar.

// using_declaration_inheritance1.cpp
#include <stdio.h>
struct B {
   virtual void f(int) {
      printf_s("In B::f(int)\n");
   }

   virtual void f(char) {
      printf_s("In B::f(char)\n");
   }

   void g(int) {
      printf_s("In B::g\n");
   }

   void h(int);
};

struct D : B {
   using B::f;
   void f(int) {   // ok: D::f(int) overrides B::f(int)
      printf_s("In D::f(int)\n");
   }

   using B::g;
   void g(char) {   // ok: there is no B::g(char)
      printf_s("In D::g(char)\n");
   }

   using B::h;
   void h(int) {}   // Note: D::h(int) hides non-virtual B::h(int)
};

void f(D* pd) {
   pd->f(1);     // calls D::f(int)
   pd->f('a');   // calls B::f(char)
   pd->g(1);     // calls B::g(int)
   pd->g('a');   // calls D::g(char)
}

int main() {
   D * myd = new D();
   f(myd);
}
In D::f(int)
In B::f(char)
In B::g
In D::g(char)

Contoh: using aksesibilitas deklarasi

Semua instans nama yang disebutkan dalam deklarasi penggunaan harus dapat diakses. Secara khusus, jika kelas turunan menggunakan deklarasi penggunaan untuk mengakses anggota kelas dasar, nama anggota harus dapat diakses. Jika namanya adalah fungsi anggota yang kelebihan beban, maka semua fungsi bernama harus dapat diakses.

Untuk informasi selengkapnya tentang aksesibilitas anggota, lihat Kontrol Akses Anggota.

// using_declaration_inheritance2.cpp
// C2876 expected
class A {
private:
   void f(char);
public:
   void f(int);
protected:
   void g();
};

class B : public A {
   using A::f;   // C2876: A::f(char) is inaccessible
public:
   using A::g;   // B::g is a public synonym for A::g
};

Lihat juga

Namespace
Kata kunci