2016-04-12 25 views
2

başvurularına uygulanmaz Referansları yayınlarken, derleyicinin Derived sınıfını Base ürününe dönüştürmeye çalıştığı ve özel dökümün hiç kullanılmadığı görülmektedir. Bu, ancak işaretçilerle sorunsuz çalışır.Özel döküm türetilmiş sınıf

Örnek:

#include <iostream> 

class Base { 
public: 
    int fn() { 
     return 42; 
    } 
}; 

class Derived : private Base { 
public: 
    operator Base&() { 
     return *dynamic_cast<Base*>(this); 
    } 

    operator Base*() { 
     return dynamic_cast<Base*>(this); 
    } 
}; 

int main() { 
    Derived d; 
    Derived &dRef = d; 

    std::cout<<static_cast<Base&>(dRef).fn()<<std::endl; // <-- error: non-reachable base >>Base<<of>>Derived<< 
    std::cout<<static_cast<Base*>(d)->fn()<<std::endl;  // OK -> "42" 
} 

Neden böyle oldu döküm özel kullanmak mümkün değil mi? İstenen davranışa ulaşmak mümkün mü (referanslar ile ulaşılamaz bir tabana "upcasting")?

+0

Temel sınıfınızın * özel * kasıtlı olduğunu fark edeceksiniz, evet? Bu amaçlanan – WhozCraig

+0

@WhozCraig, bu yüzden oyuncuya ihtiyacımız var. Yine de işaretçilerle çalışır. – alex

+0

Eh, eski (referans) hiç bir zaman çağrılmayacaktı ve derleyiciniz sizi bu konuda uyarmış olmalıydı: clang, örneğin: "Türetilmiş 'dönüştürme' temel sınıfına dönüştürme 'Base' asla kullanılmayacaktır". – WhozCraig

cevap

5

[class.conv.fct]/1. maddesi (vurgu benim):

bir dönüştürme işlevi (muhtemelen ev nitelikli) bir (muhtemelen ev nitelikli) nesneyi dönüştürmek için kullanılan hiçbir zaman

aynı nesne tipine (veya buna referans olarak), bu tip bir (muhtemelen taban sınıfına (veya a bir referansa) veya (muhtemelen cv kalifiye) void değerine.

Ve gerçekten clang bir uyarı verir:

warning: conversion function converting 'Derived' to its base class 'Base' will never be used 
operator Base&() { 
^ 

Orada göstericiler için böyle bir sınırlama, böylece static_cast<Base*>(d) çalışma biçimi ve özel dönüşüm operatörü çağırır.

std::cout << dRef.operator Base&().fn() << std::endl; 

Ancak bu durumda muhtemelen bunun için sıradan bir üye işlev oluşturmak istersiniz, ya: Gerçekten referanslar için dönüşüm operatörü kullanmak istiyorsanız

, açıkça söylemek zorunda dürüst olun ve sadece mirasın kamuya açık olmasını sağlayın.

+2

Veya kalıtım yerine yeniden kullanım için kompozisyon kullanın. –

İlgili konular