Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Anda dapat menggunakan deklarasi alias untuk mendeklarasikan nama yang akan digunakan sebagai sinonim untuk jenis yang dideklarasikan sebelumnya. (Mekanisme ini juga disebut secara informal sebagai alias jenis). Anda juga dapat menggunakan mekanisme ini untuk membuat templat alias, yang dapat berguna untuk alokator kustom.
Sintaks
using identifier = type;
Keterangan
identifier
Nama alias.
jenis
Pengidentifikasi jenis yang Anda buat aliasnya.
Alias tidak memperkenalkan jenis baru dan tidak dapat mengubah arti nama jenis yang ada.
Bentuk alias paling sederhana setara typedef
dengan mekanisme dari C++03:
// C++11
using counter = long;
// C++03 equivalent:
// typedef long counter;
Kedua bentuk ini memungkinkan pembuatan variabel jenis counter
. Sesuatu yang lebih berguna akan menjadi alias jenis seperti ini untuk std::ios_base::fmtflags
:
// C++11
using fmtfl = std::ios_base::fmtflags;
// C++03 equivalent:
// typedef std::ios_base::fmtflags fmtfl;
fmtfl fl_orig = std::cout.flags();
fmtfl fl_hex = (fl_orig & ~std::cout.basefield) | std::cout.showbase | std::cout.hex;
// ...
std::cout.flags(fl_hex);
Alias juga berfungsi dengan penunjuk fungsi, tetapi jauh lebih mudah dibaca daripada typedef yang setara:
// C++11
using func = void(*)(int);
// C++03 equivalent:
// typedef void (*func)(int);
// func can be assigned to a function pointer value
void actual_function(int arg) { /* some code */ }
func fptr = &actual_function;
Batasan typedef
mekanismenya adalah tidak berfungsi dengan templat. Namun, sintaks alias jenis di C++11 memungkinkan pembuatan templat alias:
template<typename T> using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> ptr_int;
Contoh
Contoh berikut menunjukkan cara menggunakan templat alias dengan alokator kustom—dalam hal ini, jenis vektor bilangan bulat. Anda dapat mengganti jenis apa pun untuk int
membuat alias yang nyaman untuk menyembunyikan daftar parameter kompleks dalam kode fungsi utama Anda. Dengan menggunakan alokator kustom di seluruh kode Anda, Anda dapat meningkatkan keterbacaan dan mengurangi risiko memperkenalkan bug yang disebabkan oleh kesalahan ketik.
#include <stdlib.h>
#include <new>
template <typename T> struct MyAlloc {
typedef T value_type;
MyAlloc() { }
template <typename U> MyAlloc(const MyAlloc<U>&) { }
bool operator==(const MyAlloc&) const { return true; }
bool operator!=(const MyAlloc&) const { return false; }
T * allocate(const size_t n) const {
if (n == 0) {
return nullptr;
}
if (n > static_cast<size_t>(-1) / sizeof(T)) {
throw std::bad_array_new_length();
}
void * const pv = malloc(n * sizeof(T));
if (!pv) {
throw std::bad_alloc();
}
return static_cast<T *>(pv);
}
void deallocate(T * const p, size_t) const {
free(p);
}
};
#include <vector>
using MyIntVector = std::vector<int, MyAlloc<int>>;
#include <iostream>
int main ()
{
MyIntVector foov = { 1701, 1764, 1664 };
for (auto a: foov) std::cout << a << " ";
std::cout << "\n";
return 0;
}
1701 1764 1664
Typedefs
typedef
Deklarasi memperkenalkan nama yang, dalam cakupannya, menjadi sinonim untuk jenis yang diberikan oleh bagian deklarasi jenis dari deklarasi.
Anda dapat menggunakan deklarasi typedef untuk membuat nama yang lebih pendek atau lebih bermakna untuk jenis yang sudah ditentukan oleh bahasa atau untuk jenis yang telah Anda deklarasikan. Nama typedef memungkinkan Anda untuk merangkum detail implementasi yang dapat berubah.
Berbeda dengan class
, , struct
union
, dan enum
deklarasi, typedef
deklarasi tidak memperkenalkan jenis baru; mereka memperkenalkan nama baru untuk jenis yang ada.
Nama yang dinyatakan menggunakan typedef
menempati namespace yang sama dengan pengidentifikasi lain (kecuali label pernyataan). Oleh karena itu, mereka tidak dapat menggunakan pengidentifikasi yang sama dengan nama yang dideklarasikan sebelumnya, kecuali dalam deklarasi jenis kelas. Pertimbangkan contoh berikut:
// typedef_names1.cpp
// C2377 expected
typedef unsigned long UL; // Declare a typedef name, UL.
int UL; // C2377: redefined.
Aturan persembunyian nama yang berkaitan dengan pengidentifikasi lain juga mengatur visibilitas nama yang dideklarasikan menggunakan typedef
. Oleh karena itu, contoh berikut adalah legal dalam C++:
// typedef_names2.cpp
typedef unsigned long UL; // Declare a typedef name, UL
int main()
{
unsigned int UL; // Redeclaration hides typedef name
}
// typedef UL back in scope
Contoh lain dari persembunyian nama:
// typedef_specifier1.cpp
typedef char FlagType;
int main()
{
}
void myproc( int )
{
int FlagType;
}
Saat Anda mendeklarasikan pengidentifikasi cakupan lokal dengan nama yang sama dengan typedef
, atau ketika Anda mendeklarasikan anggota struktur atau gabungan dalam cakupan yang sama atau dalam cakupan dalam, penentu jenis harus ditentukan. Contohnya:
typedef char FlagType;
const FlagType x;
Untuk menggunakan kembali nama FlagType
sebagai pengidentifikasi, anggota struktur, atau anggota gabungan, tipenya harus disediakan:
const int FlagType; // Type specifier required
Tidak cukup untuk mengatakan
const FlagType; // Incomplete specification
FlagType
karena diambil untuk menjadi bagian dari jenis , bukan pengidentifikasi yang sedang dideklarasikan ulang. Deklarasi ini diambil untuk menjadi deklarasi ilegal, mirip dengan:
int; // Illegal declaration
Anda dapat mendeklarasikan jenis apa pun dengan typedef
, termasuk jenis pointer, fungsi, dan array. Anda dapat mendeklarasikan nama typedef untuk sebuah penunjuk ke tipe struktur atau gabungan sebelum Anda mendefinisikan tipe struktur atau gabungan, selama definisi tersebut memiliki visibilitas yang sama dengan deklarasi.
Contoh
Salah satu penggunaan typedef
deklarasi adalah membuat deklarasi lebih seragam dan ringkas. Contohnya:
typedef char CHAR; // Character type.
typedef CHAR * PSTR; // Pointer to a string (char *).
PSTR strchr( PSTR source, CHAR target );
typedef unsigned long ulong;
ulong ul; // Equivalent to "unsigned long ul;"
Untuk digunakan typedef
untuk menentukan jenis dasar dan turunan dalam deklarasi yang sama, Anda dapat memisahkan deklarator dengan koma. Contohnya:
typedef char CHAR, *PSTR;
Contoh berikut menyediakan jenis DRAWF
untuk fungsi yang tidak mengembalikan nilai dan mengambil dua argumen int:
typedef void DRAWF( int, int );
Setelah pernyataan di atas typedef
, deklarasi
DRAWF box;
akan setara dengan deklarasi
void box( int, int );
typedef
sering dikombinasikan dengan struct
untuk mendeklarasikan dan memberi nama jenis yang ditentukan pengguna:
// typedef_specifier2.cpp
#include <stdio.h>
typedef struct mystructtag
{
int i;
double f;
} mystruct;
int main()
{
mystruct ms;
ms.i = 10;
ms.f = 0.99;
printf_s("%d %f\n", ms.i, ms.f);
}
10 0.990000
Redeclaration typedefs
typedef
Deklarasi dapat digunakan untuk mendeklarasikan ulang nama yang sama untuk merujuk ke jenis yang sama. Contohnya:
File sumber file1.h
:
// file1.h
typedef char CHAR;
File sumber file2.h
:
// file2.h
typedef char CHAR;
File sumber prog.cpp
:
// prog.cpp
#include "file1.h"
#include "file2.h" // OK
File prog.cpp
menyertakan dua file header, yang keduanya berisi typedef
deklarasi untuk nama CHAR
. Selama kedua deklarasi mengacu pada jenis yang sama, redeklarasi tersebut dapat diterima.
typedef
Tidak dapat menentukan ulang nama yang sebelumnya dinyatakan sebagai jenis yang berbeda. Pertimbangkan alternatif file2.h
ini :
// file2.h
typedef int CHAR; // Error
Pengkompilasi mengeluarkan kesalahan karena prog.cpp
upaya untuk mendeklarasi ulang nama CHAR
untuk merujuk ke jenis yang berbeda. Kebijakan ini meluas ke konstruksi seperti:
typedef char CHAR;
typedef CHAR CHAR; // OK: redeclared as same type
typedef union REGS // OK: name REGS redeclared
{ // by typedef name with the
struct wordregs x; // same meaning.
struct byteregs h;
} REGS;
typedefs di C++ vs. C
Penggunaan penentu typedef
dengan jenis kelas sebagian besar didukung karena praktik ANSI C mendeklarasikan struktur yang tidak disebutkan namanya dalam typedef
deklarasi. Misalnya, banyak pemrogram C menggunakan idiom berikut:
// typedef_with_class_types1.cpp
// compile with: /c
typedef struct { // Declare an unnamed structure and give it the
// typedef name POINT.
unsigned x;
unsigned y;
} POINT;
Keuntungan dari deklarasi seperti itu adalah memungkinkan deklarasi seperti:
POINT ptOrigin;
Melainkan:
struct point_t ptOrigin;
Di C++, perbedaan antara typedef
nama dan jenis nyata (dinyatakan dengan class
kata kunci , , union
struct
, dan enum
) lebih berbeda. Meskipun praktik C mendeklarasikan struktur tanpa nama dalam pernyataan typedef
masih berfungsi, itu tidak memberikan manfaat notasi seperti yang dilakukan dalam C.
// typedef_with_class_types2.cpp
// compile with: /c /W1
typedef struct {
int POINT();
unsigned x;
unsigned y;
} POINT;
Contoh sebelumnya mendeklarasikan kelas bernama POINT
menggunakan sintaks kelas typedef
yang tidak disebutkan namanya. POINT
diperlakukan sebagai nama kelas; namun, pembatasan berikut berlaku untuk nama yang diperkenalkan dengan cara ini:
Nama (sinonim) tidak dapat muncul setelah awalan
class
, ,struct
atauunion
.Nama tidak dapat digunakan sebagai nama konstruktor atau destruktor dalam deklarasi kelas.
Singkatnya, sintaks ini tidak menyediakan mekanisme apa pun untuk pewarisan, konstruksi, atau penghancuran.