免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4346 | 回复: 5
打印 上一主题 下一主题

[C++] 问个c++里friend class的问题,大虾指教,谢谢! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-06 07:10 |只看该作者 |倒序浏览
20可用积分
下面是friend class的一些介绍,这个我明白。

Friend Classes
C++ provides the friend keyword to do just this. Inside a class, you can indicate that other classes (or simply functions) will have direct access to protected and private members of the class. When granting access to a class, you must specify that the access is granted for a class using the class keyword:

friend class aClass;

Note that friend declarations can go in either the public, private, or protected section of a class--it doesn't matter where they appear. In particular, specifying a friend in the section marked protected doesn't prevent the friend from also accessing private fields. Here is a more concrete example of declaring a friend:

class Node
{
    private:
    int data;
    int key;
    // ...

    friend class BinaryTree; // class BinaryTree can now access data directly
};

Now, Node does not need to provide any means of accessing the data stored in the tree. The BinaryTree class that will use the data is the only class that will ever need access to the data or key. (The BinaryTree class needs to use the key to order the tree, and it will be the gateway through which other classes can access data stored in any particular node.) Now in the BinaryTree class, you can treat the key and data fields as though they were public:

class BinaryTree
{
    private:
    Node *root;

    int find(int key);
};
int BinaryTree::find(int key)
{
    // check root for NULL...
    if(root->key == key)
    {
        // no need to go through an accessor function
        return root->data;
    }
    // perform rest of find



我的问题是下面的:

class student_info 是class Core的友员类。
Core.h如下:
#ifndef GUARD_Core_h
#define GUARD_Core_h

#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

class Core {
public:
    Core(): midterm(0), final(0) { }
    Core(std::istream& is) { read(is); }

    std::string name() const;

    // as defined in 13.1.2/230

    virtual std::istream& read(std::istream&);
    virtual double grade() const;

    virtual ~Core() { }

protected:
    // accessible to derived classes

    std::istream& read_common(std::istream&);
    double midterm, final;
    std::vector<double> homework;

    virtual Core* clone() const { return new Core(*this); }

private:
    // accessible only to `Core'

    std::string n;
    friend class Student_info;
};

class Grad: public Core {
public:
    Grad(): thesis(0) { }
    Grad(std::istream& is) { read(is); }

    // as defined in 13.1.2/230; Note: `grade' and `read' are `virtual' by inheritance

    double grade() const;
    std::istream& read(std::istream&);
private:
    double thesis;
#ifdef _MSC_VER
    Core* clone() const { return new Grad(*this); }
#else
    Grad* clone() const { return new Grad(*this); }
#endif
};

bool compare(const Core&, const Core&);
bool compare_Core_ptrs(const Core* cp1, const Core* cp2);

#endif


student_info.h如下:

#ifndef GUARD_Student_info_h
#define GUARD_Student_info_h

#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

#include "Core.h"

class Student_info {
public:
        // constructors and copy control
        Student_info(): cp(0) { }
        Student_info(std::istream& is): cp(0) { read(is); }
        Student_info(const Student_info&;
        Student_info& operator=(const Student_info&;
        ~Student_info() { delete cp; }

        // operations
        std::istream& read(std::istream&;

        std::string name() const {
                if (cp) return cp->name();
                else throw std::runtime_error("uninitialized Student";
        }
        double grade() const {
                if (cp) return cp->grade();
                else throw std::runtime_error("uninitialized Student";
        }

        static bool compare(const Student_info& s1,
                            const Student_info& s2) {
                return s1.name() < s2.name();
        }

private:
        Core* cp;  //cp是这个类的私有数据
        int i;
};

#endif


student_info.cc如下:

#include <iostream>

#include "Core.h"
#include "Student_info.h"

using std::istream;

istream& Student_info::read(istream& is)
{
        delete cp;          // delete previous object, if any

        char ch;
        is >> ch;           // get record type

        if (ch == 'U') {
                cp = new Core(is);
        } else {
                cp = new Grad(is);
        }

        return is;
}

Student_info::Student_info(const Student_info& s): cp(0)
{
        if (s.cp) cp = s.cp->clone(); //我的问题是cp不是s的private member吗?为什么可以直接访问s.cp阿?这个也是因为友员类的关系吗?我一般看到的友员类好像不是这样的。
        int a = s.i;
}

Student_info& Student_info:perator=(const Student_info& s)
{
        if (&s != this) {
                delete cp;
                if (s.cp)           ////我的问题是cp不是s的private member吗?为什么可以直接访问s.cp阿?这个也是因为友员类的关系吗?我一般看到的友员类好像不是这样的。
                        cp = s.cp->clone();
                else
                        cp = 0;
        }
        return *this;
}


问题在student_info的拷贝构造函数和赋值操作符中,我的问题是cp不是s的private member吗?为什么可以直接访问s.cp阿?这个也是因为友员类的关系吗?我一般看到的友员类好像都是我上面给的二叉树那个例子那样的。
请大虾指点下,多谢!

[ 本帖最后由 susesuse 于 2009-6-6 07:13 编辑 ]

最佳答案

查看完整内容

类A的private成员(包括成员变量,成员函数,静态变量,静态成员函数)是限制其他类B(包括类B的成员变量,成员函数,静态变量,静态成员函数)或者自由函数对其进行访问。并不能限制类A的成员对其进行访问。Student_info::Student_info(const Student_info& s) 是Student_info的拷贝构造函数,也是Student_info的一个成员函数。它自然可以访问Student_info类的所有成员,即使是private。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
2 [报告]
发表于 2009-06-06 07:10 |只看该作者

回复 #3 susesuse 的帖子

类A的private成员(包括成员变量,成员函数,静态变量,静态成员函数)是限制其他类B(包括类B的成员变量,成员函数,静态变量,静态成员函数)或者自由函数对其进行访问。
并不能限制类A的成员对其进行访问。

Student_info::Student_info(const Student_info& s) 是Student_info的拷贝构造函数,也是Student_info的一个成员函数。它自然可以访问Student_info类的所有成员,即使是private。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
3 [报告]
发表于 2009-06-06 09:35 |只看该作者
http://bbs3.chinaunix.net/thread-1457439-1-1.html#message10573223

[ 本帖最后由 OwnWaterloo 于 2009-6-6 09:37 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-06-06 10:30 |只看该作者

回复 #2 OwnWaterloo 的帖子

谢谢楼上,我明白一些了。我看网上有人说,同一类的两个对象互为友元 ,这样理解行吗?

您能把下面这个说的更详细点吗?

访问权限是是限制“类”这一级别,而非“对象”这一级别。

论坛徽章:
0
5 [报告]
发表于 2009-06-06 11:05 |只看该作者

回复 #4 OwnWaterloo 的帖子

谢谢阿,我算是明白了。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
6 [报告]
发表于 2009-06-06 11:16 |只看该作者

回复 #5 susesuse 的帖子

原帖由 susesuse 于 2009-6-6 11:05 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=10664985&ptid=访问权限是是限制“类”这一级别,而非“对象”这一级别。 


上次说的这句话,原本是出自周星星的blog上。
觉得有那么点意思, 但仔细推敲说不过去。

如果将访问级的限制都理解为对"函数"(自由函数,成员函数,静态成员函数)的限制,也许清晰一些。

能访问C的private成员(静态/非静态成员变量,静态/非静态成员函数)的函数有:
1. C的成员函数
2. C的静态成员函数
3. C的友元(友元函数或者友元类的成员函数和静态成员函数)

能访问C的protected成员(静态/非静态成员变量,静态/非静态成员函数)的函数有:
1. C的成员函数
2. C的静态成员函数
3. C的友元(友元函数或者友元类的成员函数和静态成员函数)
4. C的子类的成员函数和静态成员函数


C的public成员(静态/非静态成员变量,静态/非静态成员函数)是所有函数都能访问的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP