从静态成员函数访问私有非静态类变量-C ++

时间:2019-09-27 11:31:39

标签: c++ oop private static-methods

可以在静态函数中访问私有非静态变量/方法吗?如是, 那么“专用”访问修饰符的用途是什么?请检查以下代码。

// Testclassheader.h file
class TestClass{
private:
int TestVariable;    //Private Variable
int TestFunction();   //Private Method

public:
static void TeststaticFn();   //Static Method

};

void TestClass::TeststaticFn()
{
   TestClass TestObj;
   TestObj.TestVariable = 10; // Compiles perfectly
   TestObj.TestFunction(); //Compiles Perfectly

}

// Another Class
//#include "Testclassheader.h"
class AnotherClass{
public:
int DummyFunc();
};

int AnotherClass::DummyFunc()
{
  TestClass AnotherObj;
  AnotherObj.TestVariable = 15; //error: 'TestVariable' is a private member of 'TestClass'
  AnotherObj.TestFunction();    //error: 'TestFunction' is a private member of 'TestClass'
}

我在Visual Studio 12中尝试了上面的代码。谁能解释为什么私有变量/方法可以在静态方法中访问(实际上不应该)?

2 个答案:

答案 0 :(得分:6)

给定类的

所有功能可以通过任何实例来访问该类的private成员。您似乎认为private限制了对该特定实例的成员函数的访问,这是不正确的。

class foo
  {
  private:
  int bar;

  // access of the function doesn't matter, but let's use public
  public: 

  // the only case you thought was legal:
  void baz()
    {
    bar = 1;
    }

  // but this is perfectly legal
  void qux(foo otherFoo)
    {
    otherFoo.bar = 1;
    }

  // also legal, as you discovered.
  static void quux(foo iPittyTheFoo)
    {
    iPittyTheFoo.bar = 1;
    }
  };

  class someOtherClass
    {
    // no function here (static or otherwise) has access to baz.

    // UNLESS you "friend someOtherClass" inside class foo.  Whether or not
    // "friend" is ever a good idea is a matter of some debate.
    };

void someGlobalFunction()
  {
  // Also cannot access bar.
  Foo a;
  a.bar = 1; // boom
  }

// nope.  Still cannot access bar.
foo b;
someOtherClass instance(b.bar); // boom

此外,“ // throws error”具有误导性。 “抛出”专门指异常处理,而不是编译时错误。编译器错误,链接器错误和运行时错误都非常不同,并且需要不同类型的问题解决方案来处理。当从不看实际错误输出的人那里寻求帮助时,您需要指定它是哪个。通常,仅复制粘贴错误本身就是一个好主意,然后我们每个人都有相同的信息。

通常来说,我怀疑您误解了public:protected:private:的目的。我们都必须在某个时候学习它。

在C ++中,public函数/方法和变量/成员(不同的人使用不同的术语)表示类的“接口”。这些是该类之外的所有内容都可以使用的东西。该界面背后发生的事与他们无关(至少从理论上来说)。

protected函数和变量可用于从该类继承的类。 “您可以通过以下方式自定义此类的版本。”

private函数和变量无所谓。没事随着程序的变化,给定类内的实现细节可能会发生巨大变化。类的初始实现可能会(颤抖)返回硬编码值:

  class X 
    {
    ...
    private:
    int Y() { return 1; }
    };

该功能的最新版本可能会在数据库中查找值,从文件中读取,无论如何。 “哪个数据库?”好的,现在我们需要一个参数...

   int Y(WhichDb thisOne) { return thisOne.lookupY(); }

因此,现在所有调用Y的地方都需要传递WhereDb(可能应该是const引用,但这是一个完全不同的主题)。通过更改Y的“函数签名”,我们破坏了所有称为Y的代码。换句话说,对Y的所有现有调用现在都是编译器错误,因为它们没有传入WhereDb。从某种意义上说,公共/受​​保护/私有定义了给定更改将影响/破坏多少代码。

私人?只是那个班。没问题,我负责该类(因为我可以更改其标题),因此修复该问题没有问题。

受保护了吗?该类,以及从该类继承的所有内容。这很容易破坏别人的密码,这通常是不好的。破坏您不负责的代码是丢失客户的好方法。

公开?任何地方的任何人都可以调用该函数。应避免对公共接口进行“重大更改”。

因此,也许您的类仅由您在公司内部,部门中使用。那时的公共更改并不重要。另一方面,某些大众图书馆确实无法做到这一点。我的意思是……他们可以,但是他们可能会惹怒很多人。

有多种方法可以更改您的公共界面而不会破坏现有代码。您可以添加新功能,也可以向现有功能添加新参数,这些功能已经过默认:void foo(int bar = 2);。叫foo()的人仍会编译(并希望仍能得到他们所依赖的行为),但是现在人们可以叫foo(3)来获得新行为。

答案 1 :(得分:4)

  

可以在静态函数中访问私有的非静态变量/方法吗?

是的,私有的非静态变量/方法可以由属于同一类的静态函数访问。

  

如果是,那么“专用”访问修饰符有什么用途?

它防止其他类访问该类的私有类成员和私有实例成员。

  

谁能解释为什么私有变量/方法可以通过静态方法访问?

因为类的所有部分都是该类的一部分。

  

实际上[私有变量/方法]不应[可用于同一类的静态方法])?

那是不正确的。