ฉันรู้สึกประหลาดใจอย่างยิ่งที่โค้ดต่อไปนี้รวบรวมและทำงาน (vc2012 & gcc4.7.2)
class Foo {
struct Bar { int i; };
public:
Bar Baz() { return Bar(); }
};
int main() {
Foo f;
// Foo::Bar b = f.Baz(); // error
auto b = f.Baz(); // ok
std::cout << b.i;
}
ถูกต้องหรือไม่ว่ารหัสนี้รวบรวมได้ดี และทำไมมันถูกต้อง? เหตุใดฉันสามารถใช้auto
กับประเภทส่วนตัวในขณะที่ฉันไม่สามารถใช้ชื่อได้ (ตามที่คาดไว้)
private
มีความสะดวกในการอธิบาย API ในวิธีที่คอมไพเลอร์สามารถช่วยบังคับใช้ มันไม่ได้มีเจตนาที่จะป้องกันการเข้าถึงชนิดBar
โดยผู้ใช้Foo
จึงไม่กีดขวางFoo
ในทางใด ๆ Bar
จากการเสนอเข้าที่โดยการกลับตัวอย่างของ
#include <iostream>
ฉบับที่คุณจำเป็นต้อง ;-)
f.Baz().i
ยังใช้ได้เช่นstd::cout << typeid(f.Baz()).name()
เดิม โค้ดที่อยู่นอกคลาสสามารถ "เห็น" ชนิดที่ถูกส่งคืนโดยBaz()
ถ้าคุณได้รับมันคุณก็ไม่สามารถตั้งชื่อมันได้