Diğer adlar ve tür tanımları (C++)
Daha önce bildirilen bir tür için eş anlamlı olarak kullanılacak bir ad bildirmek için diğer ad bildirimi kullanabilirsiniz. (Bu mekanizma, kayıt dışı olarak tür diğer adı olarak da adlandırılır). Bu mekanizmayı, özel ayırıcılar için yararlı olabilecek bir diğer ad şablonu oluşturmak için de kullanabilirsiniz.
Sözdizimi
using identifier = type;
Açıklamalar
identifier
Diğer adın adı.
type
Diğer ad oluşturduğunuz tür tanımlayıcısı.
Diğer ad yeni bir tür sunmaz ve var olan bir tür adının anlamını değiştiremez.
Diğer adın en basit biçimi C++03 mekanizmasına typedef
eşdeğerdir:
// C++11
using counter = long;
// C++03 equivalent:
// typedef long counter;
Bu formların her ikisi de türünde counter
değişkenlerin oluşturulmasını sağlar. Daha kullanışlı bir şey için bunun std::ios_base::fmtflags
gibi bir tür diğer adı olabilir:
// 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);
Diğer adlar işlev işaretçileriyle de çalışır, ancak eşdeğer tür tanımından çok daha okunabilir:
// 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;
Mekanizmanın typedef
bir sınırlaması, şablonlarla çalışmamasıdır. Ancak, C++11'deki tür diğer ad söz dizimi diğer ad şablonlarının oluşturulmasını sağlar:
template<typename T> using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> ptr_int;
Örnek
Aşağıdaki örnekte bir diğer ad şablonunun özel ayırıcıyla (bu örnekte tamsayı vektör türü) nasıl kullanılacağı gösterilmektedir. Ana işlevsel kodunuzda karmaşık parametre listelerini gizlemek için uygun bir diğer ad oluşturmak için int
herhangi bir türü yerine kullanabilirsiniz. Kodunuzun tamamında özel ayırıcıyı kullanarak okunabilirliği artırabilir ve yazım hatasının neden olduğu hataların ortaya çıkma riskini azaltabilirsiniz.
#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
Tür tanımları
Bir typedef
bildirim, kapsamı içinde bildirimin tür bildirimi bölümü tarafından verilen tür için bir eş anlamlıya dönüşen bir ad tanıtır.
Typedef bildirimlerini, dil tarafından önceden tanımlanmış olan türler veya bildirdiğiniz türler için daha kısa veya daha anlamlı adlar oluşturmak için kullanabilirsiniz. Typedef adları, değişebilecek uygulama ayrıntılarını kapsüllemenize olanak sağlar.
, , struct
union
ve enum
bildirimlerinden farklı olarakclass
, typedef
bildirimler yeni türler sunmaz; var olan türler için yeni adlar ekler.
kullanılarak typedef
bildirilen adlar diğer tanımlayıcılarla aynı ad alanını kaplar (deyim etiketleri dışında). Bu nedenle, sınıf türü bildirimi dışında daha önce bildirilen bir adla aynı tanımlayıcıyı kullanamazlar. Aşağıdaki örneği inceleyin:
// typedef_names1.cpp
// C2377 expected
typedef unsigned long UL; // Declare a typedef name, UL.
int UL; // C2377: redefined.
Diğer tanımlayıcılarla ilgili ad gizleme kuralları, kullanılarak typedef
bildirilen adların görünürlüğünü de yönetir. Bu nedenle, aşağıdaki örnek C++'da geçerlidir:
// 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
Başka bir ad gizleme örneği:
// typedef_specifier1.cpp
typedef char FlagType;
int main()
{
}
void myproc( int )
{
int FlagType;
}
Bir yerel kapsam tanımlayıcısını ile aynı ada typedef
göre bildirdiğinizde veya aynı kapsamda veya iç kapsamdaki bir yapı veya birleşimin üyesini bildirdiğinizde, tür tanımlayıcısı belirtilmelidir. Örnek:
typedef char FlagType;
const FlagType x;
Tanımlayıcının, yapı üyesinin FlagType
veya birleşim üyesinin adını yeniden kullanmak için türü sağlanmalıdır:
const int FlagType; // Type specifier required
Bunu söylemek yeterli değildir
const FlagType; // Incomplete specification
çünkü , FlagType
yeniden işlenen bir tanımlayıcı değil, türün bir parçası olarak alınır. Bu bildirim, aşağıdakine benzer şekilde yasa dışı bir bildirim olarak alınır:
int; // Illegal declaration
İşaretçi, işlev ve dizi türleri dahil olmak üzere ile typedef
herhangi bir türü bildirebilirsiniz. Tanımın bildirimle aynı görünürlüğe sahip olduğu sürece, yapıyı veya birleşim türünü tanımlamadan önce bir yapı veya birleşim türü işaretçisi için tür tanımı adı bildirebilirsiniz.
Örnekler
Bildirimlerin typedef
bir kullanımı, bildirimleri daha düzgün ve kompakt hale getirmektir. Örnek:
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;"
Aynı bildirimde temel ve türetilmiş türleri belirtmek için kullanmak typedef
için bildirimcileri virgülle ayırabilirsiniz. Örnek:
typedef char CHAR, *PSTR;
Aşağıdaki örnek, değer döndürmeden iki int bağımsız değişkeni alan bir işlevin türünü DRAWF
sağlar:
typedef void DRAWF( int, int );
Yukarıdaki typedef
ifadeden sonra bildirimi
DRAWF box;
bildirimine eşdeğer olacaktır
void box( int, int );
typedef
genellikle kullanıcı tanımlı türleri bildirmek ve adlandırmak için ile struct
birleştirilir:
// 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
Tür tanımlarının yeniden dikte edilmesi
Bildirimi, typedef
aynı türe başvurmak için aynı adı yeniden eklemek için kullanılabilir. Örnek:
Kaynak dosya file1.h
:
// file1.h
typedef char CHAR;
Kaynak dosya file2.h
:
// file2.h
typedef char CHAR;
Kaynak dosya prog.cpp
:
// prog.cpp
#include "file1.h"
#include "file2.h" // OK
Dosyaprog.cpp
, her ikisi de adı CHAR
için bildirimler içeren iki üst bilgi dosyası içerirtypedef
. Her iki bildirim de aynı türe başvurduğu sürece, böyle bir yeniden bildirim kabul edilebilir.
typedef
daha önce farklı bir tür olarak bildirilen bir adı yeniden tanımlayamaz. Şu alternatifi file2.h
göz önünde bulundurun:
// file2.h
typedef int CHAR; // Error
Derleyici, farklı bir türe başvurmak için adı CHAR
yeniden ekleme girişimi nedeniyle içinde bir hata prog.cpp
döndürür. Bu ilke aşağıdaki gibi yapılara genişletir:
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;
C++ ve C'de tür tanımları
Tanımlayıcının typedef
sınıf türleriyle kullanılması, ansi C'nin bildirimlerde typedef
adsız yapıları bildirme uygulaması nedeniyle büyük ölçüde desteklenir. Örneğin, birçok C programcısı aşağıdaki deyimi kullanır:
// 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;
Böyle bir bildirimin avantajı, aşağıdaki gibi bildirimleri etkinleştirmesidir:
POINT ptOrigin;
Onun yerine:
struct point_t ptOrigin;
C++ dilinde adlar ve gerçek türler (, , ve enum
anahtar sözcükleriyle class
bildirilir) arasındaki typedef
fark daha union
farklıdır. struct
C deyiminde adsız bir yapı bildirme uygulaması hala işe yarasa da, C'de olduğu gibi herhangi bir typedef
gösterimi yarar sağlamaz.
// typedef_with_class_types2.cpp
// compile with: /c /W1
typedef struct {
int POINT();
unsigned x;
unsigned y;
} POINT;
Yukarıdaki örnek, adlandırılmamış sınıf söz dizimini kullanarak adlı POINT
bir sınıf typedef
bildirir. POINT
sınıf adı olarak değerlendirilir; ancak, aşağıdaki kısıtlamalar bu şekilde tanıtılan adlar için geçerlidir:
Ad (eş anlamlı) bir ,
struct
veyaunion
ön ekininclass
ardından görünemez.Ad, bir sınıf bildirimi içinde oluşturucu veya yıkıcı adı olarak kullanılamaz.
Özetle, bu söz dizimi devralma, oluşturma veya yok etme mekanizması sağlamaz.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin