Constructor ไม่สามารถเข้าถึงสมาชิกส่วนตัวของคลาสของตัวเองได้

ฉันได้รับข้อผิดพลาดต่อไปนี้ใน Visual Studio 2008: ข้อผิดพลาด C2248: 'Town::Town' : ไม่สามารถเข้าถึงสมาชิกส่วนตัวที่ประกาศในคลาส 'Town' ดูเหมือนว่า Constructor จะไม่สามารถเข้าถึงสมาชิกของคลาสของตัวเองได้ มีความคิดว่าเกิดอะไรขึ้น? นี่คือรหัส:

ฉันมีสิ่งนี้:

template<class T> class Tree{...}

และคลาสนี้:

class Town{
    Town(int number):number(number){};
    ...
private: 
    int number;
};

ซึ่งใช้ในคลาสนี้:

class Country{
public:
    StatusType AddTown(Shore side, int location, int maxNeighborhoods);
private:
    Tree<Town> towns[2];
    ...
}

และนี่คือฟังก์ชัน AddTown:

StatusType Country::AddTown(Shore side, int location, int maxNeighborhoods){
    if (maxNeighborhoods<0 || location<0){
        return INVALID_INPUT;
    }
    Town* dummy= new Town(location);//Here be error C2248
    if (towns[side].find(*dummy)!=NULL){
        delete dummy;
        return FAILURE;
    }
    SouthBorder* dummyBorder;
    (side==NORTH)?dummyBorder=new SouthBorder(location,0):dummyBorder=new SouthBorder(0,location);
    if (southBorders.find(*dummyBorder)!=NULL){
        delete dummyBorder;
        return FAILURE;
    }
    towns[side].add(*dummy);
    delete dummyBorder;
    return SUCCESS;
}

person Epsilon Vector    schedule 07.06.2009    source แหล่งที่มา


คำตอบ (3)


โดยค่าเริ่มต้น ระดับการเข้าถึงชั้นเรียนเป็นแบบส่วนตัว หากคุณไม่เพิ่มสาธารณะ: ก่อนตัวสร้าง Town มันจะเป็นแบบส่วนตัว

class Town{
public: // <- add this
    Town(int number):number(number){};
    ...
private: 
    int number;
};
person David Rodríguez - dribeas    schedule 07.06.2009

รหัสนี้มีทั้งปัญหาตรรกะที่ระบุไว้ข้างต้น ทั้งการประกาศแบบไม่เปิดเผยต่อสาธารณะและการซ่อนตัวแปรสมาชิกโดยใช้ชื่อเดียวกันที่ส่งผ่านเป็นภายใน

เมื่อพิจารณาว่าเรากำลังพูดถึงตัวแปร 'ตัวเลข' เป็นตัวอย่าง

ในอดีตเช่นในตัวแปรสมาชิก c++ ที่เป็นตัวแปรภายในส่วนตัวจะมีคำนำหน้าด้วย 'm_number' หรือบางคนอาจทำเพียง '_number'

แค่ 'num' เป็นการเปลี่ยนชื่อที่ดี แต่อาจไม่ชัดเจนว่าเป็นเพียงค่าเดียวกัน ฉันคิดว่านี่เป็นปัญหาของการตั้งชื่อตัวแปรสมาชิกส่วนตัวภายในที่ยังไม่ได้รับการแก้ไขจริงๆ

Python ใช้ 'self.number' ซึ่งจะแยกความแตกต่างจาก 'number' ที่ส่งผ่านซึ่งเป็นวิธีแก้ปัญหาที่ดี

แต่ไม่ว่าแพลตฟอร์มจะเป็นเช่นไร การมีระบบการตั้งชื่อสมาชิกตัวแปรส่วนตัวที่ช่วยให้คุณหลีกเลี่ยงการแฮ็กในจุดที่ชื่อขัดแย้งกันถือเป็นเรื่องดีเสมอไป

person Ryan Christensen    schedule 07.06.2009
comment
+1 สำหรับแนวคิดทั่วไป แต่ถึงแม้จะเป็นเรื่องทั่วไป คุณไม่ควรขึ้นต้นด้วยขีดล่าง '_' เนื่องจากมาตรฐานสงวนชื่อเหล่านั้นไว้สำหรับ 'การนำไปปฏิบัติ' โดยที่การนำไปใช้งานคือคอมไพเลอร์/ตัวนำไปใช้ STL คุณยังสามารถใช้ 'this' ใน C++ ได้เหมือนกับที่คุณใช้ 'self' ใน python เพื่อแยกแยะแอตทริบิวต์จากตัวระบุอื่น ๆ (ตัวแปร/พารามิเตอร์ในเครื่อง) - person David Rodríguez - dribeas; 08.06.2009

คุณประกาศตัวแปรท้องถิ่นสำหรับฟังก์ชันที่ซ่อนตัวแปรสมาชิก:

เมือง(int number):หมายเลข(หมายเลข){};

ลองสิ่งนี้แทน

Town(int num):number(num){};

person Hans    schedule 07.06.2009
comment
รายการการเริ่มต้นมีความพิเศษเล็กน้อยสำหรับเอฟเฟกต์นี้ พารามิเตอร์ที่มีชื่อเดียวกันจะไม่ซ่อนแอตทริบิวต์ในขณะที่อยู่ในรายการการกำหนดค่าเริ่มต้น พารามิเตอร์จะซ่อนชื่อของแอตทริบิวต์ทุกครั้งที่เป็นไปได้ เมื่อคอมไพเลอร์พบ ': number(number)' 'number' แรกจะต้องเป็นแอตทริบิวต์สำหรับโค้ดที่จะคอมไพล์ 'ตัวเลข' ตัวที่สองอาจเป็นอย่างใดอย่างหนึ่งก็ได้ และพารามิเตอร์จะซ่อนแอตทริบิวต์นั้นไว้ที่นั่น (เช่นเดียวกับทุกที่ภายในบล็อกตัวสร้าง) แต่รหัส OP นั้นถูกต้อง - person David Rodríguez - dribeas; 07.06.2009