2011-04-06 122 views
10

只是想澄清一下。 抽象基類不應該有私人成員?例如C++抽象基類私人成員

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

你永遠無法訪問敏,因爲你不能創建ABC的一個實例,它不會是因爲其私人派生類。 有沒有什麼情況下你會在抽象基類中使用私有成員,或者這只是錯誤的?

+0

像那樣的私有成員沒有意義的抽象類,只是因爲它沒有任何意義在*任何其他*類。 – 2011-04-06 15:46:21

+0

@MartinhoFernandes:你是說私人數據成員從來沒有意義,或者你是在說'int'還是'myInt'? – 2011-04-06 15:57:59

+0

我在說私人數據成員沒有使用*任何地方*沒有意義。'class abc {public:virtual void foo(){};/*不再抽象*/private:int myInt;'不會使myInt更有用。 – 2011-04-06 16:00:22

回答

12

在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; 
}; 

該代碼可以確保每一個從基礎派生對象都有一個名字,那就是施工期間設置,從不在一生中改變的對象。

編輯:對於完成後,查爾斯·貝利在提醒我的是他的answer

您還可以定義純虛功能,並且在這種情況下,私有屬性也有道理:

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

就目前來看,你的例子沒有意義。

但是,抽象基類允許擁有成員函數定義,而後者又可以訪問基類中的私有成員數據。

1

並非抽象基類中的所有方法都必須是純虛擬的。你可能有一些對所有子類都有用的方法。因此,如果您在修改內部狀態的基類中具有某些功能,那麼您將擁有這些私有成員。

2

通常不建議將數據成員放在抽象類中,但在示例中沒有任何技術上的錯誤。在公開訪問的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 
+0

你沒有在'''abc'''構造函數中初始化'''myInt'''變量 - 這是正常的嗎? :) – isnullxbh 2017-02-20 09:24:35

-5

您可以通過此快捷方式

代碼是在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);