C++ 友元/多态类错误

标签 c++ class polymorphism friend access-control

在 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/

相关文章:

c++ - 两种模板类型的 sizeof,当两者都派生自一个基类时

python - 如何将对象存储在动态生成的变量中?

c++ - 抽象类和指针

c++ - 重载 == 运算符导致丢弃限定符错误

c++ - 子类中的成员对父类成员的引用?

c++ - 模板类中的方法仅对某些模板参数正确

用于生成部分 switch 语句的 C++ 模板?

c++ - 获取 vector<float> 中 k 个最大值的索引的有效方法

Java大类组织

c++ - 如何在不知道底层类型的情况下从模板化父类取回值?