为什么 class 的方法无法访问我的 class 的某些字段?
Why method of class does not have access to some field of my class?
我尝试实现 linked_ptr
。这是一项学习任务。这是我的代码的一部分:
template <class T>
class linked_ptr
{
public:
//***************
linked_ptr<T>(linked_ptr<T> const& other)
{
p = other.p;
left_ptr = &other;
right_ptr = other.right_ptr;
if (other.right_ptr != nullptr)
{
(other.right_ptr)->left_ptr = this;
}
other.right_ptr = this;
}
template <class U>
linked_ptr<T>(linked_ptr<U> const& other)
{
p = other.p;
left_ptr = &other;
right_ptr = other.right_ptr;
if (other.right_ptr != nullptr)
{
(other.right_ptr)->left_ptr = this;
}
other.right_ptr = this;
}
private:
T *p;
mutable linked_ptr const* left_ptr;
mutable linked_ptr const* right_ptr;
};
class A
{
public:
int a = 0;
A(int aa)
{
a = aa;
}
};
class B : public A
{
public:
B(int bb)
{
a = bb;
}
};
int main()
{
linked_ptr<B> a(new B(5));
linked_ptr<A> b(a);
return 0;
}
我有一些错误:
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
ptr::linked_ptr<B> *' to 'const smart_ptr::linked_ptr<A> *'
ptr::linked_ptr<B> *' to 'const smart_ptr::linked_ptr<A> *'
linked_ptr<A> *const ' to 'const smart_ptr::linked_ptr<B> *'
linked_ptr<A> *const ' to 'const smart_ptr::linked_ptr<B> *'
我不知道这些错误与什么有关。有趣的是,linked_ptr<T>(linked_ptr<T> const& other)
效果很好,但 linked_ptr<T>(linked_ptr<U> const& other)
却不行。
我该如何解决这些问题?我可以将两个复制构造函数合并为一个吗?
P.S。当然,U
是 T
的 child。
当T
和U
是不同的类型时,那么linked_ptr<T>
和linked_ptr<U>
是不同的类型。这意味着他们看不到对方的私有成员。
您需要结交其他 linked_ptr
的朋友:
template <class T>
class linked_ptr {
// The rest...
template<class U>
friend class linked_ptr;
};
你没有class,你有class模板。也就是模板,配方,用于创建classes。输入类型(T
),输出类型 class。每个 T
一个完全不同的、单独的 class。就像 classes A
和 B
不能访问彼此的私有字段一样, classes linked_ptr<A>
和 linked_ptr<B>
(和 linked_ptr<int>
,就此而言)。
如果您需要此访问权限,则必须将适当的 friend
声明添加到您的 class 模板中:
template <class T>
class linked_ptr
{
template <class U>
friend class linked_ptr;
// ... the rest as before
};
其他解决方案仅解决第一个编译错误。使用模板友元声明将允许 linked_ptr<A>
访问 linked_ptr<B>
私有状态,但它们不允许您将 linked_ptr<A> *
分配给 linked_ptr<B> *
。
树本身应该由基本类型统一组成。
int main()
{
linked_ptr<A> a(new B(5));
linked_ptr<A> b(a);
return 0;
}
如果你这样做,你就不需要好友声明了。 (或者您需要使构造函数更复杂,将 link_ptr<U>
变形为 linked_ptr<T>
。但这需要更智能的指针或克隆或其他东西......这带来了:我不确定什么是 "smart" 关于这些指针。如前所述,没有进行内存管理并且 new B(5)
丢失。)
此外,我知道这只是伪代码,但 B::B(int bb)
构造函数需要显式初始化其基数:
class B : public A
{
public:
B(int bb)
: A(bb)
{
}
};
我在您的代码中看到的一种做法可能会增加混淆,它会将 left_ptr
和 right_ptr
声明为 linked_ptr
。 C++ 允许您在定义中通过其模板名称引用 class,但这并不意味着这是一个好主意。我认为代码(和上面的错误)如果代码写成更清晰:
T *p;
mutable linked_ptr<T> const* left_ptr;
mutable linked_ptr<T> const* right_ptr;
我尝试实现 linked_ptr
。这是一项学习任务。这是我的代码的一部分:
template <class T>
class linked_ptr
{
public:
//***************
linked_ptr<T>(linked_ptr<T> const& other)
{
p = other.p;
left_ptr = &other;
right_ptr = other.right_ptr;
if (other.right_ptr != nullptr)
{
(other.right_ptr)->left_ptr = this;
}
other.right_ptr = this;
}
template <class U>
linked_ptr<T>(linked_ptr<U> const& other)
{
p = other.p;
left_ptr = &other;
right_ptr = other.right_ptr;
if (other.right_ptr != nullptr)
{
(other.right_ptr)->left_ptr = this;
}
other.right_ptr = this;
}
private:
T *p;
mutable linked_ptr const* left_ptr;
mutable linked_ptr const* right_ptr;
};
class A
{
public:
int a = 0;
A(int aa)
{
a = aa;
}
};
class B : public A
{
public:
B(int bb)
{
a = bb;
}
};
int main()
{
linked_ptr<B> a(new B(5));
linked_ptr<A> b(a);
return 0;
}
我有一些错误:
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
cannot access private member declared in class 'smart_ptr::linked_ptr<B>'
ptr::linked_ptr<B> *' to 'const smart_ptr::linked_ptr<A> *'
ptr::linked_ptr<B> *' to 'const smart_ptr::linked_ptr<A> *'
linked_ptr<A> *const ' to 'const smart_ptr::linked_ptr<B> *'
linked_ptr<A> *const ' to 'const smart_ptr::linked_ptr<B> *'
我不知道这些错误与什么有关。有趣的是,linked_ptr<T>(linked_ptr<T> const& other)
效果很好,但 linked_ptr<T>(linked_ptr<U> const& other)
却不行。
我该如何解决这些问题?我可以将两个复制构造函数合并为一个吗?
P.S。当然,U
是 T
的 child。
当T
和U
是不同的类型时,那么linked_ptr<T>
和linked_ptr<U>
是不同的类型。这意味着他们看不到对方的私有成员。
您需要结交其他 linked_ptr
的朋友:
template <class T>
class linked_ptr {
// The rest...
template<class U>
friend class linked_ptr;
};
你没有class,你有class模板。也就是模板,配方,用于创建classes。输入类型(T
),输出类型 class。每个 T
一个完全不同的、单独的 class。就像 classes A
和 B
不能访问彼此的私有字段一样, classes linked_ptr<A>
和 linked_ptr<B>
(和 linked_ptr<int>
,就此而言)。
如果您需要此访问权限,则必须将适当的 friend
声明添加到您的 class 模板中:
template <class T>
class linked_ptr
{
template <class U>
friend class linked_ptr;
// ... the rest as before
};
其他解决方案仅解决第一个编译错误。使用模板友元声明将允许 linked_ptr<A>
访问 linked_ptr<B>
私有状态,但它们不允许您将 linked_ptr<A> *
分配给 linked_ptr<B> *
。
树本身应该由基本类型统一组成。
int main()
{
linked_ptr<A> a(new B(5));
linked_ptr<A> b(a);
return 0;
}
如果你这样做,你就不需要好友声明了。 (或者您需要使构造函数更复杂,将 link_ptr<U>
变形为 linked_ptr<T>
。但这需要更智能的指针或克隆或其他东西......这带来了:我不确定什么是 "smart" 关于这些指针。如前所述,没有进行内存管理并且 new B(5)
丢失。)
此外,我知道这只是伪代码,但 B::B(int bb)
构造函数需要显式初始化其基数:
class B : public A
{
public:
B(int bb)
: A(bb)
{
}
};
我在您的代码中看到的一种做法可能会增加混淆,它会将 left_ptr
和 right_ptr
声明为 linked_ptr
。 C++ 允许您在定义中通过其模板名称引用 class,但这并不意味着这是一个好主意。我认为代码(和上面的错误)如果代码写成更清晰:
T *p;
mutable linked_ptr<T> const* left_ptr;
mutable linked_ptr<T> const* right_ptr;