簡體   English   中英

能夠更改私有 const 類成員

[英]Able to change private const class member

為什么 c++ 允許從外部類更改私有成員(const 與否)。 班級以外的任何人都不能更改 const 成員。 這似乎打破了 C++ 封裝。

#include <iostream>
#include <cstdlib>
#include <string>

class A
{
    const std::string s;
    public:

    A():s{"abcd"}{};
    const std::string& f()
    {
        return s;
    }
};

int main()
{
    A a;
    std::string &s = const_cast<std::string&>(a.f());
    s="efgh";
    std::cout<<s<<std::endl;
    std::cout<<a.f()<<std::endl;
    return 0;
}

編譯是在 wandbox 在線編譯器上使用 c++11 完成的。

g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.69.0/gcc-head/include -std=c++11

輸出是:

efgh
efgh

我預計編譯錯誤: std::string &s = const_cast(af());

如果沒有方法可以這樣做,我不應該被允許以任何方式從外部更改私有類成員(常量或非常量)。

這是未定義的行為。

它允許您這樣做的事實並不意味着這是正確的,通過非 const 修改const對象是未定義的行為,任何事情都可能發生,包括工作的外觀。

如果沒有方法可以這樣做,我不應該被允許以任何方式從外部更改私有類成員(常量或非常量)。

數據成員的可訪問性與成員函數的可訪問性及其功能有些無關,您可以擁有私有成員和公共函數,它們可以在不違反成員固有屬性的情況下更改或授予對它們的某些訪問權限。 在您的示例中, foo正在向const std::string返回一個 ref ,它清楚地表達了意圖(它是一個 const 對象),但在外面您違反了該意圖。

它沒有。

當您使用const_cast去除const時,您實際上關閉了您所要求的保護。 那是你的責任。 C++ 必須允許這在一般情況下允許“黑客”; 根據其理念,它不會認真努力阻止您違反合同。 但是,最終,您確實違反了合同,所以這是您的錯!

因此,您的程序具有未定義的行為; 即代碼壞了。

當您通過成員函數直接公開成員時,繞過private是完全正確的。 (訪問說明符保護名稱,而不是對象,並且您的main不使用私有名稱。)同樣,這是您的選擇。 破壞了類的封裝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM