问题 c ++抽象基类私有成员


只是想要一些澄清。 抽象基类是否应该没有私有成员?例如

class abc{
public:
  virtual void foo()=0;
private:
  int myInt;
}

你永远不能访问myInt,因为你不能创建一个abc的实例,它不会在派生类中,因为它是私有的。 是否有任何情况你会在抽象基类中使用私有成员,或者这只是错误的?


4028
2018-04-06 15:41


起源

像这样的私人成员在抽象类中没有意义,就像它没有意义一样 任何其他 类。 - R. Martinho Fernandes
@MartinhoFernandes:你是说私人数据成员从来没有意义,或者你在说些什么 int 要么 myInt 尤其是? - CB Bailey
我说的是没有使用过的私有数据成员 随地 没有意义。 class abc{ public: virtual void foo(){}; /*not abstract anymore*/ private: int myInt; 不会使myInt更有用。 - R. Martinho Fernandes
@Charles:不,不可能。 foo 没有实现,因为它是纯虚拟的。 - R. Martinho Fernandes
@Martinho Fernandes没有规则说抽象方法不能实现。 - Mark B


答案:


在C ++中,您可以拥有一个具有非纯虚方法的抽象类。在这种情况下,根据设计,拥有私人会员是有意义的:

class base {
   std::string name;
public:
   base( std::string const & n ) : name(n) {}
   std::string const & getName() const { return name; }

   virtual void foo() = 0;
};

该代码确保从base派生的每个对象都具有一个名称,该名称在构造期间设置,并且在对象的生命周期内永远不会更改。

编辑:在Charles Bailey提醒我这件事之后完成了 回答

你也可以定义 纯虚拟 函数,在这种情况下,私有属性也可能有意义:

// with the above definition of base
void base::foo() {
   std::cout << "My name is " << name << std::endl;
}

13
2018-04-06 15:44





通常不建议在抽象类中使用数据成员,但是在您的示例中没有技术上的错误。在执行中 foo,您可以使用公开访问 myInt 无论你喜欢什么目的。

例如:

class abc{
public:
  virtual void foo()=0;
private:
  int myInt;
};

class xyz : public abc
{
    virtual void foo();
};

#include <iostream>
#include <ostream>

void xyz::foo()
{
    std::cout << "xyz::foo()\n";
    abc::foo();
}

void abc::foo()
{
    std::cout << "abc::foo(): " << myInt++ << '\n';
}

#include <memory>

int main()
{
    std::auto_ptr<abc> p( new xyz() ); // value-initialization important
    p->foo();
    p->foo();
}

输出:

xyz::foo()
abc::foo(): 0
xyz::foo()
abc::foo(): 1

2
2018-04-06 15:56



你没有初始化 myInt 变量 abc 构造函数 - 这是正常的吗? :) - isnullxbh


并非抽象基类中的所有方法都必须是纯虚方法。您可能有一些对所有子类都有用的方法。因此,如果您在基类中有一些正在修改内部状态的功能,那么您将拥有私有成员。


1
2018-04-06 15:45





如果你使用 模板方法设计模式 (实施 开放/封闭原则),这是很常见的 private 抽象基类的成员。


1
2018-04-06 16:02





就目前而言,你的例子毫无意义。

但是,允许抽象基类具有成员函数定义,而这些定义又允许访问基类中的私有成员数据。


0
2018-04-06 15:44





您可以通过此快捷方式访问私人会员

代码是PHP

abstract class myclass1 
{ 
           private $var="46789";
       public function test($valuetoset)
       {
            echo $this->var = $valuetoset;

       } 
} 

class myclass2 extends myclass1
{ 


} 

$obj = new myclass2();
$obj->test(78);

-5
2017-07-08 12:44