Friend Fonksiyonlar ve Sınıflar
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 32 / 104.
Bazen sınıfınızın dışındaki bir işlevin veya sınıfın, sınıfınızın private üyelerine erişmesi gerekir. Bu üyeleri public yapmak yerine C++, kapsüllemeyi korurken seçici erişim izni vermek için friend anahtar sözcüğünü sunar.
Arkadaş işlevi bir sınıfın içinde bildirilir, ancak o sınıfın bir üyesi değildir. Sınıfın private ve protected üyelerine erişebilir:
class Box {
double width;
public:
Box(double w) : width(w) {}
// printWidth'i friend olarak bildir
friend void printWidth(const Box& b);
};
// Friend fonksiyon tanımı - bir üye fonksiyon DEĞİL
void printWidth(const Box& b) {
std::cout << b.width; // private üyeye erişebilir
}printWidth öğesinin sınıfın dışında kapsam çözümleme operatörü olmadan tanımlandığına dikkat edin. Bu, özel erişim ayrıcalıklarına sahip olan normal bir işlevdir.
Ayrıca, bir sınıfın tamamını friend yaparak tüm üye işlevlerine private üyelere erişim izni verebilirsiniz:
class Engine {
int horsepower;
friend class Mechanic; // Mechanic özel üyelere erişebilir
public:
Engine(int hp) : horsepower(hp) {}
};
class Mechanic {
public:
void diagnose(const Engine& e) {
std::cout << e.horsepower; // İzin verildi - Mechanic bir friend
}
};Arkadaşlık karşılıklı değildir - Engine, Mechanic'i arkadaş olarak ilan ederse, Mechanic Engine'in private üyelerine erişebilir, ancak bunun tersi geçerli değildir. Arkadaşları tutumlu kullanın; çünkü sınıflar arasında sıkı bir bağımlılık oluştururlar. En çok operatör aşırı yüklemesi ve yakından ilişkili yardımcı işlevler için kullanışlıdırlar.
Görev
KolayMessageReader sınıfının SecureMessage sınıfında depolanan şifrelenmiş mesajları okuyabilmek için özel erişime ihtiyaç duyduğu güvenli bir mesajlaşma sistemi oluşturalım. Bu, arkadaş işlevlerini ve arkadaş sınıflarını kullanmak için mükemmel bir senaryodur.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
SecureMessage.h: Özel mesaj verilerini depolayan ve güvenilir varlıklara seçici erişim sağlayan birSecureMessagesınıfı tanımlayın. Sınıfınız şunlara sahip olmalıdır:- Özel üyeler:
content(string) vesecretKey(int) - İçeriği ve gizli anahtarı alan bir kurucu
- Özel üyelere erişebilmesi için
MessageReadersınıfını arkadaş sınıfı olarak tanımlayın - Yalnızca sağlanan anahtar gizli anahtarla eşleşiyorsa içeriği, aksi takdirde
"Access Denied"döndüren bir arkadaş işlevi olandecryptMessage(const SecureMessage& msg, int key)işlevini tanımlayın
Ardından
MessageReadersınıfını aynı başlık dosyasında tanımlayın:- Mesajın özel
contentüyesine doğrudan erişip onu döndürenreadContent(const SecureMessage& msg)yöntemi - Sağlanan anahtarın mesajın
secretKeydeğeriyle eşleşip eşleşmediğini kontrol eden ve"Valid"veya"Invalid"döndürenverifyKey(const SecureMessage& msg, int key)yöntemi
Son olarak
decryptMessagearkadaş işlevini sınıflardan sonra tanımlayın.- Özel üyeler:
main.cpp: Hem arkadaş işlevlerini hem de arkadaş sınıflarını çalışırken gösterin. Bir mesaj içeriğini, gizli anahtarı ve test anahtarını girdiden okuyun (her biri ayrı bir satırda), ardından:- İçerik ve gizli anahtarla bir
SecureMessageoluşturun - Bir
MessageReadernesnesi oluşturun - Okuyucunun
readContent()yöntemini kullanarak"Reader access: <content>"yazdırın - Test anahtarıyla
verifyKey()işlevini kullanarak"Key verification: <result>"yazdırın - Test anahtarıyla arkadaş işlevini kullanarak
"Decrypt with test key: <result>"yazdırın - Özgün gizli anahtarla arkadaş işlevini kullanarak
"Decrypt with correct key: <result>"yazdırın
- İçerik ve gizli anahtarla bir
Arkadaş işlevlerinin sınıfın dışında, kapsam çözümleme operatörü kullanılmadan tanımlandığını unutmayın: bunlar özel erişim ayrıcalıklarına sahip normal işlevlerdir. Arkadaş olan MessageReader sınıfı, tüm yöntemlerinde SecureMessage sınıfının özel üyelerine doğrudan erişebilir.
std::stoi() kullanarak anahtar girdilerini dizelerden tamsayılara dönüştürün. #include "SecureMessage.h" kullanarak başlık dosyanızı main.cpp dosyasına dahil edin.
Kendin dene
#include <iostream>
#include <string>
#include "SecureMessage.h"
using namespace std;
int main() {
// Girdiyi oku
string messageContent;
string secretKeyStr;
string testKeyStr;
getline(cin, messageContent);
getline(cin, secretKeyStr);
getline(cin, testKeyStr);
int secretKey = stoi(secretKeyStr);
int testKey = stoi(testKeyStr);
// TODO: İçerik ve gizli anahtar ile bir SecureMessage oluştur
// TODO: Bir MessageReader nesnesi oluştur
// TODO: Print "Reader access: <content>" using readContent()
// TODO: Print "Key verification: <result>" using verifyKey() with test key
// TODO: Print "Decrypt with test key: <result>" using decryptMessage with test key
// TODO: Print "Decrypt with correct key: <result>" using decryptMessage with secret key
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic KonteynerKendi başına pratik yap: Online C++ derleyicisi