1

以下代码在 C++ 中是否合法。访问朋友类成员的公共方法?我知道这听起来令人困惑,最好的方式是在代码中展示它。我想知道 TestClassC::Method() 在下面的代码中是否有效?

我已经编译(g++)并且它可以工作,但是,我遇到了一种情况,它在 TestClassC::Method() 的其他机器/发行版上产生分段错误。这让我想知道 this->classA_Ptr->classB.Method(); 在 C++ 中是合法的。

#include <iostream>

using namespace std;

class TestClassB
{
   public:
      TestClassB(void){};
      ~TestClassB(void){};
      void Method(void){
         cout << "Hello Again" << endl;
      }
};


class TestClassC; //Forward Declaration
class TestClassA
{
   friend class TestClassC;

   public:
      TestClassA(void){};
      ~TestClassA(void){};

   private:
      TestClassB  classB;
};


class TestClassC
{
   public:
      TestClassC(TestClassA* a_Ptr){
         this->classA_Ptr = a_Ptr;
      }
      ~TestClassC(void){};

      void Method(void){
         //Is this Valid/Legal ???
         this->classA_Ptr->classB.Method();
      }

   private:
      TestClassA*  classA_Ptr;
};



int main()
{
    cout << "Hello world!" << endl;

    TestClassA testClassA;
    TestClassC classC(&testClassA);

    classC.Method();

    return 0;
}
4

3 回答 3

4

public/private/protected 访问器修饰符是在编译时强制执行的,而不是在运行时。SEGFAULT 是运行时错误,而不是编译时错误。所以,将来,如果你得到一个 SEGFAULT,你可以确定它与访问级别无关。听起来您的困惑是基于访问修饰符是否直接、间接、传递等应用。访问修饰符以最简单和直接的方式工作:它们仅直接应用于已声明的函数或变量在该类中并控制通过给定类对这些项目的访问。一旦您有权访问此类项目,进一步的访问权限完全由该项目自己的访问修饰符决定。

SEGFAULT 通常表示非法内存访问。如果您遇到 SEGFAULTS,请查看您取消引用指针的位置(只要您有 *X 或 X->Y)。SEGFAULTS 的常见原因包括取消引用 NULL、非一数组访问,以及通过指针使用对象,其中相关对象已因超出范围而被删除。

于 2010-08-20T03:18:34.563 回答
2

是的。朋友规范使 TestClassC 可以访问 TestClassA 的任何受保护或私有成员。这意味着它可以访问 classB 成员。之后,正常规则适用于 TestClassC 可以对该成员执行的操作。由于 Method() 是公共的,因此允许 TestClassC 调用它,就像它通过任何其他方式获得了 TestClassB 实例一样。


关于段错误:

公共/受保护/私有/朋友都是编译时限制。它们应该对运行时代码的操作没有影响。

这是段错误的确切代码吗?或者它只是在概念上类似的东西?如果它不是完全相同的代码,那么您是否验证了所有指针在有问题的代码中实际上都是有效的?

于 2010-08-20T03:10:21.693 回答
1

只要类是明确可访问的,并且我们有一个有效的对象表达式来访问它,调用任何类的公共方法都是有效/合法的。事实上,这就是为什么它首先被公开的原因。您的代码对我来说似乎很好。

于 2010-08-20T03:09:21.870 回答