2014-01-18 3 views
-1

У меня проблема с двумя производными классами. Мне нужно, чтобы кто-то получил в качестве аргумента другой, но мой код не работает (я дал ему больше пояснений).C++ производные классы, один - аргумент другого

класс:

#include<iostream> 
#include<stdexcept> 

using namespace std; 

template <typename T> class A; 
template <typename T> class B; 
template <typename T> class C; 

template <typename T> class A{ 

protected: 

T **m; 

void allocate_mem(T ***ptr){ 
    *ptr = new T*[1]; 
    (*ptr)[0] = new T[1]; 
} 

public: 

A(){ 
    throw logic_error("Error!"); 
} 

~A(){ 
    delete[] m[0]; 
    delete[] m; 
} 

T say_elem(){ 
    return m[0][0]; 
} 

}; 

template <typename T> class B: public A<T>{ 

public: 

B(int val){ 
    A<T>::allocate_mem(& this->m); 
    A<T>::m[0][0] = val; 
} 

}; 

template <typename T> class C: public A<T>{ 

public: 

C(double val){ 
    A<T>::allocate_mem(& this->m); 
    A<T>::m[0][0] = 1; 
} 

void renew(const B<T> &b){ 
    if(A<T>::b.say_elem() > 0){ 
     A<T>::m[0][0] = 1000; 
    } 
} 

}; 

главная:

#include<iostream> 
#include "class.cpp" 

using namespace std; 


int main(int argc, char **argv){ 

B <int> bbb(4); 

C <double> ccc(5); 

ccc.renew(bbb); 

//no matching function for call to 'C<double>::renew(B<int>&)' 

return 0; 

} 

ошибка указано выше, что мне нужно делать?

+0

Вы должны пометить A :: say_elem() const, если вы хотите использовать update() с ссылкой на константу B, а затем вызвать say_elem(). – DaBrain

+0

Я не понимаю, где я должен использовать A :: say_elem() const ... – MBall

+0

'void renew (const B & b) {b.say_elem(); } 'не будет компилироваться, потому что вы не можете вызывать неконстантные методы объекта const b. Вы должны написать 'T say_elem() const {...}' в определении класса A. – DaBrain

ответ

0

Ok, я совместил правильный ответ Jefffrey с моей запиской от комментариев, чтобы дать полные компиляции и запуск кода (который отбросит logic_error («Ошибка!»), кстати, но это не по теме).

#include<iostream> 
#include<stdexcept> 

using namespace std; 

template <typename T> class A; 
template <typename T> class B; 
template <typename T> class C; 

template <typename T> class A{ 
protected: 

    T **m; 

    void allocate_mem(T ***ptr){ 
     *ptr = new T*[1]; 
     (*ptr)[0] = new T[1]; 
    } 

public: 

    A(){ 
     throw logic_error("Error!"); // remove this line for expected behavior 
    } 

    ~A(){ 
     delete[] m[0]; 
     delete[] m; 
    } 

    T say_elem() const { 
     return m[0][0]; 
    } 

}; 

template <typename T> class B: public A<T>{ 
public: 

    B(int val){ 
     A<T>::allocate_mem(& this->m); 
     A<T>::m[0][0] = val; 
    } 
}; 

template <typename T> class C: public A<T>{ 
public: 

    C(double val){ 
     A<T>::allocate_mem(& this->m); 
     A<T>::m[0][0] = 1; 
    } 

    template <typename U> 
    void renew(const B<U> &b){ 
     if(b.A<U>::say_elem() > 0){ 
      A<T>::m[0][0] = 1000; 
     } 
    } 
}; 

int main(int argc, char **argv){ 
    B <int> bbb(4); 
    C <double> ccc(5); 

    ccc.renew(bbb); 

    return 0; 
} 
+0

Спасибо! Оно работает! – MBall

4

Вы пытаетесь позвонить C<T>::renew(const B<T> &) с неправильным аргументом. Что ожидает renew (при вызове экземпляра C<double>) есть const B<double>&, а не const B<int>&. Это два совершенно разных класса. Если вы хотите, чтобы позволить B класса с другим параметром шаблона, templatize функции:

template<class U> 
void renew(const B<U> &b) { 
    if(b.say_elem() > 0){ 
     m[0][0] = 1000; 
    } 
} 
+0

это дает мне другие ошибки: 'b' не является членом 'A ', 'int ** A :: m' защищен, статический элемент данных 'A :: m' – MBall

+0

@MBall, извините. См. Окончательное редактирование. – Shoe

+0

Это не работает снова ... – MBall

Смежные вопросы