2013-02-27 11 views
6

aşağıda Stroustup kitabında "C++ programlama dili" (üçüncü baskı), sayfa 420 ayıklandı paragraf: Çünkü bir işaretçi (bu örnekte s) sanal bir üyesineAşağıdaki ifadenin yanlış olduğunu mu düşünüyorsun ya da bir şey mi özlüyorum?

, ofset bir tür belleğe bir nesnenin konumuna bağlı değildir. Bu nedenle, sanal bir üyeye ait işaretçisi, 'da aynı nesne düzeni her ikisi de kullanıldığı sürece farklı adres boşlukları arasında güvenle iletilebilir. Sıradan işlevlere ilişkin işaretçiler gibi, sanal olmayan üye işlevlerine ilişkin işaretçiler adres boşlukları arasında değiştirilemez.

Bu paragraftaki son tümceye itiraz ediyorum. Aşağıda, nonvirtual üye işlevleri, foo() ve foo1() işaretçilerinin, bir taban nesnesi a ve türetilmiş bir nesne b arasında bir sorun olmadan değiştirildiği bir kod parçacığı bulacaksınız.

Yapılması gerekenler, türetilmiş sınıftaki foo() veya foo1() tabanındaki işlevlerden herhangi birinin aşırı yüklenmesi, bu durumda derleyici aşağıda gösterildiği gibi bir hata yayacaktır. , (Standart) C++, bir program ya da daha çok işlemde tam bir adres alanı vardır:

#include <iostream> 

class A 
{ 
    int i; 
    public: 
    A() : i(1) {} 
    void foo() { std::cout << i << '\n'; } 
    void foo1() { std::cout << 2 * i << '\n'; } 
}; 

class B: public A 
{ 
    int j; 
    public: 
    B() : A(), j(2) {} 
// void foo() { std::cout << j << '\n'; } 
}; 

int main() 
{ 
    typedef void (A::* PMF)(); 
    PMF p = &B::foo; // error C2374: 'p' redefinition, multiple initialization 
         // if foo() is overloaded in B. 
    PMF q = &B::foo1; 
    B b; 
    (b.*p)(); 
    (b.*q)(); 

    A a; 
    (a.*p)(); 
    (a.*q)(); 
} 
+6

"Adres alanları arasında değişim" okumam, bir işaretçinin bir işletim sisteminde * başka bir işleme * aktarılması gibi bir şeydi. – ulidtko

cevap

1

Bu cümle doğrudur. Bu nedenle, ulidtko'nun işaret ettiği gibi, bu cümle, farklı süreçlerin adres alanları arasındaki sanal ve sanal olmayan üye işlevlerine işaretçi değişimi yapma olasılıklarını ifade etmektedir.

A olmayan sanal üye işlevi, bir sınıfın hemen hemen (bu işaretçi) için diyoruz nesneye örtük argüman standart bir işlevdir. Bu şekilde, işleminizin adres alanına yükleme sırasında bazı adresleri atanır. Adres alanınızda tam olarak bittiği yer kesinlikle platformunuza bağlıdır ve bu üye işlevinin dinamik olarak bağlantılı bir kitaplığın parçası olup olmadığı. Asıl nokta, iki süreç için mutlaka aynı adres değildir. Bu nedenle, bir göstergenin başka bir süreçte böyle bir işlevi yürütmesi ve yürütmesi, potansiyel olarak 'makinenizi ateşe (TM)' getirecektir.

bir fonksiyon hemen hemen hareketsiz 'Eğer yürütme atlamak ve ona senin bu işaretçi geçmesi bellekte bazı adrese', gibi sanal olmayan üye işlevi aynıdır ancak içinden çağrılan sanal üye doğrudan yerine sanal işlev tablosu (vtable). Yani sanal üye işlevinin bir işaretçisi, nesnenizin sanal işlev tablosuna hemen hemen bir dizin. Bu işlevin çağrılması, nesnenin işaretçisini almak, belki de nesnenin vtable'ına ulaşmak için işaretçiyi arttırmak ve bu tablonun verilen dizinindeki adrese atlamak, nesnenin adresini olarak iletmek işaretçisi '. Bu vtable aracılığıyla bu dolaylı yollama, adres boşlukları arasındaki sanal üye işlevine işaretçiyi değiştirmeyi sağlar.

Sorumluluk reddi: "Ne hakkında konuştuğumu gerçekten biliyorum" bölümüne biraz sıkıyorum. Öyleyse bir şeyleri daha da basitleştirdim veya daha kötüsü, yanlış bilgi dağıtımıyla uğraştım, cevabımı parçalamaktan çekinmeyin;).

0

daima doğru olup öyleyse, adresini kontrol edebilir ve hafıza adresine

Çünkü hiçbir fiziksel işaretçi yok göreceksiniz sanal bellek gibi var olacaktır Bir işaretçi bir sanal üyesi bir işaretçi (ler bu örnekte) bir çeşit ofsettir, bir nesnenin hafızasındaki yerine bağlı değildir. Bu nedenle, sanal bir üyeye yönelik bir işaretçi, aynı nesne düzeni her ikisinde de kullanıldığı sürece, farklı adres boşlukları arasında güvenli bir şekilde geçirilebilir. Sıradan işlevlere işaretçiler gibi, sanal olmayan üye işlevlerine yönelik işaretçiler adres alanları arasında değiştirilemez.

İlgili konular