總結:
protected的構造函數,和private的構造函數,類似, 都是防止外部直接實例化對象,只能通過static方法才能new出對象,其實也不一定是new,主要是棧上創建被限制了,詳見下面的例子說明
區別在於protected,可以被繼承,只能進行派生類,而private的,不能派生,所有事情都必須在當前class內部實現
通常protected這種情況,class內部沒有static方法,其目的就是為了讓類只能被繼承,不能實例化當前類,只能實例化子類。 構造,拷貝構造,復制運算符都是protected。 但是析構函數要聲明成 protected,因為如果析構函數為private,派生類就不能調用。
注意,對於private構造函數,這里有一個破局的方式,如果在class類內部的一個方法,eg get_instance()方法中,返回一個臨時的對象,此時是可以在棧上創建成功,也可以進行析構,但是返回棧上的臨時實例的引用或指針,本身就是有問題的。如果返回的是實例,而不是指針,就要調用拷貝構造函數,這個拷貝構造函數也是在外部調用的,如果拷貝構造函數是private的,則編譯不通過。
通常,是把這個方法聲明為static,里面的局部變量也聲明為static,這種其實就是一種單例模式,只是這種單例,對象是在static內存區,不是在堆上面
public A& A::get_instance()
{
A a; //此時可以創建成功,因為是A內部的function,可以調用A的構造函數,即使是private
return a; // 這里return,a會進行析構,也是類內部調用,可以編譯通過。但是返回的是一個棧上的實例,調用結束后,內存已經釋放,不符合編程規范。
}
private, 這種情況,通常就是單例模式,不能被繼承,也不能在棧上實例化,只能在static方法中new出對象。
而,對應的,構造函數,拷貝構造函數,復制運算符都是private的,防止其他方式產生對象
析構函數,則
protected類型的,還有一個情況需要說明,參見鏈接 https://bbs.csdn.net/topics/392913065
// C++構造函數是protect的,子類的普通函數無法訪問,但是子類的構造函數可以訪問
class Base
{
protected: // protected
Base()
{
}
Base(const Base& base)
{
}
const Base& operator = (const Base&)
{
}
static void SFun()
{
}
void Fun()
{
}
};
class Son : public Base
{
public:
void Fun()
{
Base *p = new Base(); // error C2248: 'Base::Base': cannot access protected member declared in class 'Base'
Fun(); // OK
SFun(); // OK
}
Son()
{
}
Son(const Son & son)
{
}
};
其實本質:
本質是new 了一個新的base的實例,這個實例和當前Son的實例不是同一個,也就是son只能訪問自己內部的base類的protected方法
new出來的是另外一個base實例,跟當前實例沒有關系,是兩個相互獨立的實例,因此son實例不能訪問另外一個實例的protected方法
原因解釋:
https://en.cppreference.com/w/cpp/language/access
protected的構造函數只能在派生類構造函數的初始化列表上進行訪問,以對對象本身進行初始化。
其它protected成員函數在派生類中也只能基於派生類去訪問。
Protected member access
Protected members form the interface for the derived classes (which is distinct from the public interface of the class).
A protected member of a class Base can only be accessed
1) by the members and friends of Base
2) by the members and friends (until C++17) of any class derived from Base, but only when operating on an object of a type that is derived from Base (including this)
1. 被Base的成員和友元訪問。
2. 被任何派生類對象的成員和友元訪問,並且這個僅僅是在操作這個派生類對象時。顯然可以看出,只能通過派生類對象調用操作派生類對象,而不能在派生類里獨立地去調用基類的構造方法去創建Base對象。
https://bbs.csdn.net/topics/392913065
========================= 百度知道上面很好的一個回答
https://www.cnblogs.com/this-543273659/archive/2011/08/02/2125487.html