Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;对同一类类型的引用公开私有成员_C++_Oop_Pass By Reference_Private Members - Fatal编程技术网

C++ C++;对同一类类型的引用公开私有成员

C++ C++;对同一类类型的引用公开私有成员,c++,oop,pass-by-reference,private-members,C++,Oop,Pass By Reference,Private Members,关于这一点的详细讨论如下: 使用整数长度的线对象的简单示例。operator+重载功能可以访问另一行的专用长度(参数const line&line,即添加到此行的行)。对于非运算符重载函数(printOtherLine)和友元函数(printFriendLine)也是如此。再一次,作为参数传递的行不是此对象 为什么会这样 #include <iostream> class Line { public: Line() { length

关于这一点的详细讨论如下:

使用整数长度的线对象的简单示例。
operator+
重载功能可以访问另一行的专用长度(参数
const line&line
,即添加到
行的行)。对于非运算符重载函数(
printOtherLine
)和友元函数(
printFriendLine
)也是如此。再一次,作为参数传递的行不是
对象

为什么会这样

#include <iostream>

class Line
{
   public:
      Line()
      {
         length = 0;
      }
      Line(int length)
      {
         this->length = length;
      }
      Line operator+(const Line &line)
      {
         Line newLine(this->length + line.length); // I would have thought 
                                                  // this would be line.getLength()
                                                  // instead of line.length
         return newLine;
      }
      int getLength()
      {
         return length;
      }
      void printOtherLine(const Line &otherLine){
         std::cout << "Other Line: " << otherLine.length << std::endl;
      }
      void printLine(int lineNumber){
         std::cout << "Line " << lineNumber << ": " << this->length << std::endl;
      }
      friend void printFriendLine(const Line &friendlyLine);
   private:
      int length;
};

void printFriendLine(const Line &friendlyLine){
   std::cout << "Friendly Line: " << friendlyLine.length << std::endl;
}

// This function will not compile
// void printUnassociatedLine(const Line &line){
//    std::cout << "Unassociated Line: " << line.length << std::endl;
// }

int main()
{
   Line l1(10);
   l1.printLine(1);
   Line l2(15);
   l2.printLine(2);
   Line l3 = l1 + l2;
   l3.printLine(3);
   Line l4(7);
   l3.printOtherLine(l4);
   printFriendLine(l4);
   return 0;
}

在C++中,X类的所有代码都可以访问X的所有部分,不管哪个对象。 这甚至包括嵌套在X中的类定义中的代码

对于我来说,这是一个事后合理化的推测,但访问限制的目的是使类更容易正确使用,而对于其他代码更难错误使用。该类自己的代码是可信的,并且无论如何都必须使用该类的所有代码。因此,以任何方式限制类自己的代码都没有多大意义


关于访问受保护的数据成员,有一个有趣的技术问题。类
Base
中引入的受保护数据成员可以在派生类
派生的
中直接访问,但仅适用于静态已知类型为
派生的
或派生自
派生的类的对象。这确保了您不会仅仅通过从公共基类派生而无意中访问并使代码依赖于其他类的内部

class Base
{
protected:
    int x_      = 666;
};

class Derived
    : public Base
{
public:
    auto uh_oh( Base const& other ) const
        -> int
    { return x_ * other.x_; }           //← Nyet!
};

auto main()
    -> int
{
    Derived a
    Derived b;
    return a.uh_oh( b );
}
有两种常见的解决方法,其中一种确实需要这种访问。一种是在基类中引入访问器函数。另一个是使用类型系统漏洞作为成员指针,如下所示:

class Base
{
protected:
    int x_      = 666;
};

class Derived
    : public Base
{
public:
    auto uh_oh( Base const& other ) const
        -> int
    { return x_ * other.*&Derived::x_; }        // A somewhat dirty trick.
};

auto main()
    -> int
{
    Derived a;
    Derived b;
    return a.uh_oh( b );
}

这里还有一个隐含的最佳实践问题:当您有一个像
getLength
这样的访问器,并且还可以访问“成员变量
length
”时,最好使用一个还是另一个


好的,可能是后来有人希望更改实现,例如,长度可能是以某种方式计算的,而不是直接存储的,如果代码通常使用accessor函数,那么这样做的工作量可能会更少。但另一方面,使用访问器编写代码可能需要更多的工作,调试此类代码也可能需要更多的工作。所以,至少就我所知,每种情况都取决于常识,直觉决定 对于我来说,这是一个事后合理化的推测,但访问限制的目的是使类更容易正确使用,而对于其他代码更难错误使用。该类自己的代码是可信的,并且无论如何都必须使用该类的所有代码。因此,以任何方式限制类自己的代码都没有多大意义


关于访问受保护的
数据成员,有一个有趣的技术问题。类
Base
中引入的受保护数据成员可以在派生类
派生的
中直接访问,但仅适用于静态已知类型为
派生的
或派生自
派生的类的对象。这确保了您不会仅仅通过从公共基类派生而无意中访问并使代码依赖于其他类的内部

class Base
{
protected:
    int x_      = 666;
};

class Derived
    : public Base
{
public:
    auto uh_oh( Base const& other ) const
        -> int
    { return x_ * other.x_; }           //← Nyet!
};

auto main()
    -> int
{
    Derived a
    Derived b;
    return a.uh_oh( b );
}
有两种常见的解决方法,其中一种确实需要这种访问。一种是在基类中引入访问器函数。另一个是使用类型系统漏洞作为成员指针,如下所示:

class Base
{
protected:
    int x_      = 666;
};

class Derived
    : public Base
{
public:
    auto uh_oh( Base const& other ) const
        -> int
    { return x_ * other.*&Derived::x_; }        // A somewhat dirty trick.
};

auto main()
    -> int
{
    Derived a;
    Derived b;
    return a.uh_oh( b );
}

这里还有一个隐含的最佳实践问题:当您有一个像
getLength
这样的访问器,并且还可以访问“成员变量
length
”时,最好使用一个还是另一个


好的,可能是后来有人希望更改实现,例如,长度可能是以某种方式计算的,而不是直接存储的,如果代码通常使用accessor函数,那么这样做的工作量可能会更少。但另一方面,使用访问器编写代码可能需要更多的工作,调试此类代码也可能需要更多的工作。所以,至少就我所知,每种情况都取决于常识,直觉决定

您现在在更新中链接到的问题是否回答了您的问题?如果是这样的话,我会帮你关闭这个。或者,如果我的答案没有提供比你在那里发现的更多的东西,你可以删除它。你现在在更新中链接的问题是否回答了你的问题?如果是这样的话,我会帮你关闭这个。或者,如果我的答案没有提供比你在那里发现的更多的东西,你可以删除它。