gpt4 book ai didi

C++ 友元/多态类错误

转载 作者:行者123 更新时间:2023-12-03 12:50:58 25 4
gpt4 key购买 nike

在 C++ 中,我使用多态类和友元来创建一个基本的“ friend 组”。但是,当我尝试访问类人(男孩类的 friend )的私有(private)年龄函数时,我无法访问它。有什么问题吗?

/* Polymorphic Classes and Class Friendship */
#include <iostream>
class Person{
public:
Person(char* name, int age) : Name(name), Age(age){}
char* Name;
virtual void Speak(void){
std::cout << "I am a person called " << Name << std::endl;
}
virtual ~Person(void){delete this;}
private:
int Age;
};
class Boy : public Person{
friend class Person;
public:
Boy(char* name, int age, Person* Friend) : Person(name, age), MyFriend(Friend){}
void Speak(void){
std::cout << "I am a boy called " << Name << ". My friend " << MyFriend->Name << "'s age is " << MyFriend->Age /* Error here */ << std::endl;
}
~Boy(void){delete this;}
private:
Person* MyFriend;
};
int main(void){
Person* John = new Person("John", 12);
Boy* James = new Boy("James", 14, John);
Boy* Keith = new Boy("Keith", 18, James);
John->Speak();
James->Speak();
John->~Person();
James->~Boy();
Keith->~Boy();
return (0);
}

最佳答案

技术问题:

C++ 友元是单向的。

尝试使用protected来授予对派生类的访问权限。

代码审查:

/* Polymorphic Classes and Class Friendship */

在 C++ 中避免使用 C /**/ 多行注释是个好主意,因为它们不嵌套,并且有些/许多程序员使用它们来注释掉代码以进行调试。

优先使用 C++ //(单)行注释

#include <iostream>

好的。

class Person{
public:

好的。

    Person(char* name, int age) : Name(name), Age(age){}

第一个参数应该是char const*。例如,如果没有 const,在使用符合 C++11 的编译器时,您将无法传递文字字符串。

    char* Name;

这里的原始指针需要与构造函数的形式参数匹配。

实际上,它被初始化为构造函数指针参数的简单拷贝,它将任何 Person 实例的生命周期限制为实际参数的生命周期。

std::string 是一个更加灵活且不会出现问题的选择。

    virtual void Speak(void){
std::cout << "I am a person called " << Name << std::endl;
}

由于此函数不是 const,因此无法在 const 对象上调用它。

此外,void 是 C 主义,在 C++ 中不好。

在 C 语言中,它表示该函数不带任何参数。在 C++ 中这是不必要的,即 void 是不必要的废话。此外,C 甚至没有成员函数。

    virtual ~Person(void){delete this;}

再说一遍,void 是不好的。

在这种情况下,删除这个是非常不好的。

private:
int Age;

唯一的问题是未能对数据成员应用某些命名约定。例如,像 age_ (请注意,下划线位于末尾),或者像 my_agemyAge .

};

好的。

class Boy : public Person{

好的。

friend class Person;

毫无意义,因为 Person 类无法访问此类中的任何内容。

public:
Boy(char* name, int age, Person* Friend) : Person(name, age), MyFriend(Friend){}

同样,应该是char const*。或者std::string const&

    void Speak(void){
std::cout << "I am a boy called " << Name << ". My friend " << MyFriend->Name << "'s age is " << MyFriend->Age /* Error here */ << std::endl;
}

在这里,如果编译器支持它,请添加一个覆盖,以便编译器检查您是否确实覆盖了基类函数,例如void Speak() override { .

换句话说,抛弃void,这是不必要的C主义措辞,但要添加override,这是非常有用的。

    ~Boy(void){delete this;}

void 不好。

在这种情况下,删除这个是非常不好的。

private:
Person* MyFriend;

与之前一样,这再次限制了 Boy 实例的生命周期。

};

好的。

int main(void){

void 不好。

    Person* John = new Person("John", 12);
Boy* James = new Boy("James", 14, John);
Boy* Keith = new Boy("Keith", 18, James);
John->Speak();
James->Speak();
John->~Person();

到目前为止还好。

    James->~Boy();
Keith->~Boy();

永远不要显式调用析构函数。好吧,一个真正经验丰富的程序员可能会在使用放置 new 进行分配时这样做:它在语言中是有原因的。但作为初学者,即使拥有一两年的专业经验,也不要这样做。

    return (0);

技术上可以,但没有必要。 main 默认返回 0。

}

关于C++ 友元/多态类错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20772930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com