c++ 将公共成员函数设置为特定类的私有函数

iovurdzv  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(215)

有没有一种方法可以使一个公共成员函数对某些类是私有的?我需要这样做的原因是因为一些类必须使用其他东西来代替公共成员函数,否则会有严重的bug,但无论如何都很容易忘记并这样做。示例:

  1. class Location {
  2. std::list<Person*> everyonePresent;
  3. public:
  4. const std::list<Person*>& getEveryonePresent() const {return everyonePresent;}
  5. };
  6. class DoSomething {
  7. Person& person;
  8. std::list<Person*> everyoneVisible;
  9. public:
  10. DoSomething(Person& p) : person(p), everyoneVisible(p.getLocation().getEveryonePresent()) {
  11. // everyoneVisible now removes those who are hiding.
  12. }
  13. void execute() {
  14. // ....
  15. ApproachSomeone(person, everyoneVisible).execute();
  16. // ...
  17. }
  18. };

现在ApproachSomeone::execute()可能会在不应该使用person.getLocation().getEveryonePresent()时意外使用它。但是Location::getEveryonePresent()需要是公共的,因为它在很多地方都被使用,但是ApproachSomeone是少数几个永远不能使用它的类之一。ApproachSomeone是一个类,因为它在许多其他地方使用(命令模式)。

drkbr07n

drkbr07n1#

如果你愿意做一些依赖注入,或者愿意做一个类到抽象基类的显式转换以获得对私有成员函数的访问,那么有一种方法可以在每个函数的基础上对访问进行建模。
我曾经在一个类需要多个“朋友”的情况下使用过这些方法,但是这些朋友应该对不同的成员函数有不同的访问权限。做正确的事情仍然比较容易,但获得“私人”访问并非不可能。这是一个很好的折衷方案,可以检查代码中谁可以访问什么(因此也可以在代码审查中检测误用)。
现场演示:https://onlinegdb.com/TFVGm-HVW
首先,我们创建两个接口,用于每个类访问class A

  1. #include <iostream>
  2. class interface_for_class_b
  3. {
  4. public:
  5. virtual void method_for_class_b() = 0;
  6. };
  7. class interface_for_class_c
  8. {
  9. public:
  10. virtual void method_for_class_c() = 0;
  11. };

然后,创建一个class A,它继承了两者,但保留了private的实现。这对所有人隐藏了成员函数。

  1. class A :
  2. public interface_for_class_b,
  3. public interface_for_class_c
  4. {
  5. public:
  6. void some_public_method()
  7. {
  8. std::cout << "A::some_public_method()\n";
  9. }
  10. private:
  11. void method_for_class_b() override
  12. {
  13. std::cout << "A::method_for_class_b()\n";
  14. };
  15. void method_for_class_c() override
  16. {
  17. std::cout << "A::method_for_class_c()\n";
  18. };
  19. };

然后,使用依赖注入:

  • class B接收interface_for_class_b
  • class C接收interface_for_class_c
  1. class B
  2. {
  3. public:
  4. explicit B(interface_for_class_b& a) :
  5. m_interface_to_a{ &a } { }
  6. void some_method()
  7. {
  8. std::cout << "B::some_method()\n";
  9. // B can access "private" function through the explicit interface.
  10. m_interface_to_a->method_for_class_b();
  11. }
  12. private:
  13. interface_for_class_b* m_interface_to_a;
  14. };
  15. class C
  16. {
  17. public:
  18. explicit C(interface_for_class_c& c) :
  19. m_interface_to_a{ &c } { }
  20. void some_method()
  21. {
  22. std::cout << "C::some_method();\n";
  23. m_interface_to_a->method_for_class_c();
  24. }
  25. private:
  26. interface_for_class_c* m_interface_to_a;
  27. };

下面是我们如何使用这些类:

  1. int main()
  2. {
  3. A a;
  4. B b{ a }; // inject dependency to give b access to "private"functions
  5. C c{ a };
  6. a.some_public_method();
  7. // a.method_for_class_b();
  8. // is not accessible, it is private
  9. b.some_method();
  10. c.some_method();
  11. // if you don't want to or cannot do dependency injection
  12. // there is an alternative way to get access to the specific methods
  13. // this explicit step says you want detailed access to class a
  14. // so it is also self-documenting.
  15. interface_for_class_b& itf{ a };
  16. itf.method_for_class_b();
  17. return 0;
  18. }
展开查看全部

相关问题