Reputation: 51
I made a class template looks like below, as base class for other classes to inherit from, and it would work fine as expected.
But my question is, The code still compiles even if I change 'protected' of class 'Operation' to 'private', even Matmul(which inherits class 'Operation') is modifying vector called 'edgeIn' which is declared as 'private'.
I can't understand why something like this should be allowed... Shouldn't compiler trigger error message on this? (derived class shouldn't modify private member of base class)
template<typename T>
class Operation{
private: //Would compile fine even if I change this to 'private!'
class edge{
public:
edge(Tensor<T> tensor, Operation<T> &from, Operation<T> &to) {
this->tensor = tensor;
this->from = from;
this->to = to;
}
Operation<T> from;
Operation<T> to;
Tensor<T> tensor;
};
std::vector<edge> edgeIn; //edges as inputs of this operation
std::vector<edge> edgeOut; //edges as outputs of this operation
private:
//disable copy constructor (NOT ALLOWED)
Operation(Operation<T>& rhs) = default;
//disable move operator (NOT ALLOWED)
Operation<T>& operator=(Operation<T> &rhs) = default;
int operationId;
};
template<typename T>
class Matmul: public Operation<T>{
public:
Matmul(std::initializer_list<std::pair<Tensor<T>, Operation<T>>> args);
};
template<typename T>
//from Operation<T>, to This operation
Matmul<T>::Matmul(std::initializer_list<std::pair<Tensor<T>, Operation<T>>> args){
for(auto elem: args){
typename Operation<T>::edge info{elem.first, elem.second, *this};
this->edgeIn.emplace_back(info); //modifying member of base class
}
}
Upvotes: 0
Views: 134
Reputation: 76305
In the code you've shown, it's allowed because it's not wrong. Here's a simpler example:
template <class Ty>
class base {
int i; // private
};
template <class Ty>
class derived : base {
void set(int ii) { i = ii; }
};
At this point, if you write
derived<int> di;
di.set(3); // illegal: i is not accessible
you'll get an access error, as you expect.
But the original template isn't wrong, because the code might do this:
template <>
class base<int> {
public:
int i;
};
Now you can write
derived<int> di;
di.set(3);
and it's okay, because i
is public in base<int>
. You still can't write
derived<double> dd;
dd.set(3); // illegal: i is not accessible
Upvotes: 1