2010-07-14 3 views
4

J'ai obtenu le code suivantfonction membre ne peut pas accéder à un membre privé

#include <iostream> 
#include <string> 

template <typename T> 

class demo 
{ 
    T data; 
    public: 
    demo(); 
    demo(demo const&k); 
    demo(const T&k); 
    demo& operator=(const demo &k); 

    template<typename T1> 
    demo(const demo<T1>&k); 

    template<typename T1> 
    demo<T>& operator=(const demo<T1>&k); 

    ~demo(); 
}; 

template <typename T> 
demo<T>::demo():data(){} 

template<typename T> 
demo<T>::demo(demo const& k):data(k.data){} 

template<typename T> 
demo<T>::demo(const T&k):data(k){} 

template<typename T> 
demo<T>& demo<T>::operator=(demo const &k) 
{ 
    if ((void*)this == (void*)&k) { // assignment to itself? 
     return *this; 
     } 
    this->data=k.data; 
    return *this; 
} 

template<typename T> 
    template<typename T1> 
    demo<T>& demo<T>::operator=(demo<T1> const &k) 
    { 
    if ((void*)this == (void*)&k) { // assignment to itself? 
     return *this; 
     } 

    this->data=k.data; 
    return *this; 
    } 

template<typename T> 
    template<typename T1> 
    demo<T>::demo(const demo<T1>&k):data(k.data){} 

template<typename T> 
demo<T>::~demo(){} 

int main() 
{ 
    demo<std::string> k(std::string("hello")); 
    demo<std::string >l=k; 
    demo<int> x(10); 
    demo<double> p=x; //error here 
} 

Pourquoi puis-je obtenir l'erreur ici? Pour autant que je sache, p est en cours de copie initialisée à x. Ainsi,

demo<T>::demo(const demo<T1>&k):data(k.data){} 

est appelée. Mais puisque data est un membre privé, j'obtiens une erreur 'demo<T>::data' : cannot access private member declared in class 'demo<T>'. Pourquoi?

Je sais que les fonctions membres d'une classe peuvent accéder à des membres privés, alors pourquoi ai-je une erreur? Que dois-je faire pour corriger l'erreur?

Répondre

8

Parce que demo<T> et demo<T1> sont considérés comme des types différents, ils peuvent ne pas accéder aux données privées de l'autre.

façon de résoudre ce easist est en ajoutant une fonction accesseur public et l'utiliser:

template <typename T> 
class demo 
{ 
public: 
    const T &get_data() const { return data; } 
    ... 
}; 

template<typename T> 
template<typename T1> 
demo<T>::demo(const demo<T1>&k):data(k.get_data()){} 
3

Comme répondu par R Samuel Klatchko devant moi, et demo<T>demo<T1> ne sont pas les mêmes types.

La solution à votre problème serait de déclarer les autres classes ami:

class demo 
{ 
    T data; 
    public: 
    demo(); 
    demo(demo const&k); 
    demo(const T&k); 
    demo& operator=(const demo &k); 

    template<typename T1> 
    demo(const demo<T1>&k); 

    template<typename T1> 
    demo<T>& operator=(const demo<T1>&k); 

    ~demo(); 

    template<typename T1> // This will enable demo<T> and demo<T1> 
    friend class demo ;  // to see each other's privates as friends 
          // ought to do... 
}; 
Questions connexes