ฉันรู้สึกประหลาดใจอย่างยิ่งที่โค้ดต่อไปนี้รวบรวมและทำงาน (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()ถ้าคุณได้รับมันคุณก็ไม่สามารถตั้งชื่อมันได้