是否有無論如何我可以在沒有繼承的情況下訪問類中的受保護變量。C++受保護的訪問
class ClassA{
protected:
int varA;
};
class ClassB{
protected:
ClassA objectA;
};
ClassB theMainObject;
我想通過theMainObject訪問varA。
是否有無論如何我可以在沒有繼承的情況下訪問類中的受保護變量。C++受保護的訪問
class ClassA{
protected:
int varA;
};
class ClassB{
protected:
ClassA objectA;
};
ClassB theMainObject;
我想通過theMainObject訪問varA。
我假設修改ClassA的定義是被禁止的。
這是給你一個取巧的辦法,但我不鼓勵你使用它:)
class ClassA
{
protected:
int varA;
};
class ProtectedRemover // magic thing
{
public: // <- Note this! :)
int varA;
};
class ClassB
{
protected:
ClassA objectA;
public: // Just add two methods below
int getProtectedVarA()
{
return reinterpret_cast<ProtectedRemover*>(&objectA)->varA;
}
void setProtectedVarA(int i)
{
reinterpret_cast<ProtectedRemover*>(&objectA)->varA = i;
}
};
int main()
{
ClassB theMainObject;
// Set protected thing.
theMainObject.setProtectedVarA(3);
// Get protected thing.
std::cout << theMainObject.getProtectedVarA() << std::endl;
}
因此,有訪問和修改保護/私有數據的方式。從theMainObject
)
-1這是未定義的行爲,因爲這些類型與編譯器無關請參閱,特別是如果'ClassA'具有OP沒有顯示給我們的虛擬方法。 – 2011-03-15 13:17:36
問題男人沒有虛擬功能!爲什麼這裏的人們都充滿了願意投票? 我知道你也發佈了一個答案,但仍然不公平:) :) 爲什麼你認爲作者不知道如何添加訪問器到ClassA? :)你的答案應該先下來投票:) – 2011-03-15 13:35:23
+在我的例子中沒有任何未定義的行爲! :) – 2011-03-15 13:45:19
有一個存取函數是唯一的方法,即;
public:
int getVarA(){return varA;}
你應該讓'INT getCarA()const'。 – 2011-03-15 13:08:57
不是唯一的辦法,請閱讀我的文章;) – 2011-03-15 13:48:07
你是對的@ Space_C0wb0y,我通常懶得標記常量函數:p – deek0146 2011-03-15 14:36:46
你可以做classB
朋友classA
class ClassA{
protected:
int varA;
friend ClassB;
}
但使用存取可能會更好,因爲你是不是類耦合在一起。
class ClassA{
int getA() { return varA;}
void setA(int a) { varA = a; }
protected:
int varA;
}
friend
是你friend.Use通過提的,你要訪問的在其中ü要使用類朋友類的關鍵字!
你不能,而且很有可能不應該訪問varA
直接;
誰在想這是不可能的,投了。 protected
與無關類(如您的兩個示例類)的私有相同,因此varA
不具有可見性。使用ClassA
的正常API來操縱其狀態。
如果varA
是ClassA
結果狀態的一部分,你只需要讀取權限,那麼你應該公開訪問添加到類:
public:
int getVarA() const
{
return varA;
}
-1 downvoting我的創造性的答案,因爲你認爲作者不知道如何添加訪問者! :) – 2011-03-15 13:37:57
我同意。但我不打算投下它,因爲我非常感謝幫助。 – user346443 2011-03-15 13:59:24
除了使ClassB的ClassA的一個朋友那裏是達到ClassA內部的一些標準和非標準攻擊。你可以閱讀關於他們的Herb Sutter's article。
添加標準的getter/setter函數:
int ClassA::GetVarA()
{
return varA;
}
BOOL ClassA::SetVarA(int nNewVar)
{
// Perform verifications on nNewVar... Return FALSE if didn't go well.
// We're satisfied. Set varA to the new value.
varA = nNewVar;
return TRUE;
}
作爲標記B mentionned,通過Hovhannes Grigoryan的提出的解決方案是不是安全,也許會有意想不到的行爲,因爲ProtectedRemover和CLASSA無關....
我在過去使用這一點,它可能會更安全,我認爲:
class ClassA
{
protected:
int varA;
};
class ProtectedRemover : public ClassA // now, they are related!
{
public: // <- Note this! :)
int getA() { return varA; }
void setA(int a) { varA = a; }
};
class ClassB
{
protected:
ClassA objectA;
public: // Just add two methods below
int getProtectedVarA()
{
return ((ProtectedRemover)*(&objectA))->getA();
}
void setProtectedVarA(int i)
{
((ProtectedRemover)*(&objectA))->setA(i);
}
};
注意它提出萬無一失得到待定的行爲....但可以爲L而不是原來的解決方案,其中ProtectedRemover和classA是無關的......並且如果ClassA具有屬性的音調也更容易做到!
除非你真的沒有別的選擇,否則還是不推薦的(不能通過讓你的班級朋友或添加settre/getter來修改classA)!
沒有真的不可能....
+1好的問題;) – 2011-03-15 13:18:40