收录日期:2020/10/29 07:32:18 时间:2016/07/11 11:05:18 标签:C++ 语言
//A.h
class A
{
   public:
         A();
         virtual ~A();
 void call();
   protected:
         virtual void write();
};

//A.cpp
#include "A.h"
#include <stdio.h>

A::A(){}
A::~A(){}
void A::write()
{
    printf("A::write");
}

void A::call()
{
    A* a = new B;
    a->write();

}

//B.h
#include "A.h"
class B:public A
{
      public:
         B();
         virtual ~B()
   protected:
         void write();
       
}

//B.cpp
#include "B.h"
#include <stdio.h>

B::B(){}
B::~B(){}
void B::write()
{
    printf("B::write");
}

//main.cpp
int main()
{
     A* a = new B;
     a->call();
     a->write();//Error:不能访问protected函数。

}

我的问题:为什么在call函数中可以访问被保护的write函数?而在main函数中却不可以?如果我把main()中的a->write()注释掉,程序可以编译通过。



protected表示这个成员可以被类内部成员访问
也可以被派生类内部访问
但是不能在类外访问
call函数是类的成员函数 是自己人的
这个保护是对类外的而言
protected
权限是基类的内部和继承类的内部!
外面是不可以的!
A* a = new B; 
a->write(); //这里调用B的write函数
protected主要是为了方便子类来访问或者是重写

而在main函数中只能访问类的共有成员,即对外的接口.你的protected的成员调用当然不能出现在这里.
个人愚见
我知道这个道理,但是

void A::call() 

    A* a = new B; 
    a->write(); 



call 虽然是在A的内部,但是这里new 了一个B的实列,然后给了A,用的是a->write();
如果call函数写成如下:

void A::call() 
{  
    write(); 

这肯定是可以。 但是a->write();这个write还相当与在内部访问?和main()中的a->write();有区别?
我的问题:为什么在call函数中可以访问被保护的write函数?而在main函数中却不可以?如果我把main()中的a->write()注释掉,程序可以编译通过。 

因为main函数不是B类的友元或者说main不具备访问write的权限

这样:
#include <stdio.h>
#include <iostream>
using namespace std;

class A 

public: 
A(); 
virtual ~A(); 
void call(); 
protected: 
/////main作为友元啦哈哈
friend int main();
virtual void write(); 
}; 


class B:public A 

public: 
B();
virtual ~B(); 
protected: 
void write(); 
/////main作为友元啦哈哈
friend int main();
} ;


B::B(){} 
B::~B(){} 
void B::write() 

printf("B::write"); 


A::A(){} 
A::~A(){} 
void A::write() 

printf("A::write"); 


void A::call() 

A* a = new B; 
a->write(); 



//main.cpp 
int main() 

A* a = new B; 
a->call();
a->write();
B *b = new B;
b->write();//Error:不能访问protected函数。 
delete b;



呵呵,这里你的a和b在main里面。相当于main直接访问write!
定义protect 中的
只能在 他本身和继承他的类中访问,而在其他的地方都不可以访问
那么我得出这么一个结论 不知道正确不:

protected 函数不能在外部调用,这个是大家都确认的。
而在内部是可以调用的,无论是直接调用如:
void A::call() 
{  
    write(); 
}

还是通过实例 如:
void A::call() 

    A* a = new B; 
    a->write(); 
   
    A _a;
    _a.write();

}

都是可以的。只要write()出现在内部。

这样解释对吗? 
楼上的各位已经说的满清楚了,这里顺便提一下楼主貌似有内存泄露的问题哦!

void A::call() 

    A* a = new B; 
    a->write(); 
    //函数返回之前还是释放一下内存比较好

引用 5 楼 gongyue1983 的回复:
我知道这个道理,但是 

void A::call() 

    A* a = new B; 
    a->write(); 



call 虽然是在A的内部,但是这里new 了一个B的实列,然后给了A,用的是a->write(); 
如果call函数写成如下: 

void A::call() 
{  
    write(); 

这肯定是可以。 但是a->write();这个write还相当与在内部访问?和main()中的a->write();有区别?

你定义的指针a指向的变量也是类内部的变量  怎么不可以访问类里面的函数呢  
而你在main函数里的变量 对类来说相当于 外家人
正确,包括private也一样,当作内部友元看待
引用 8 楼 gongyue1983 的回复:
那么我得出这么一个结论 不知道正确不: 

protected 函数不能在外部调用,这个是大家都确认的。 
而在内部是可以调用的,无论是直接调用如: 
void A::call() 
{  
    write(); 


还是通过实例 如: 
void A::call() 

    A* a = new B; 
    a->write(); 
  
    A _a; 
    _a.write(); 



都是可以的。只要write()出现在内部。 

这样解释对吗? 

可以这样理解
引用 8 楼 gongyue1983 的回复:
那么我得出这么一个结论 不知道正确不: 

protected 函数不能在外部调用,这个是大家都确认的。 
而在内部是可以调用的,无论是直接调用如: 
void A::call() 
{  
    write(); 


还是通过实例 如: 
void A::call() 

    A* a = new B; 
    a->write(); 
  
    A _a; 
    _a.write(); 



都是可以的。只要write()出现在内部。 

这样解释对吗? 

可以这样理解
up
主函数调用
int main() 

    A* a = new B;    //这种结果在c++ 中 定义后  这个a是A的对象
    a->call();       //凋用成员函数  没问题
                          /*void A::call() 
                            { 
                              A* a = new B; //定义类A的对象a申请个B的空间
                             a->write(); // 这个函数中调用是函数体内部的凋用,而函数本身在这个A类中
                             } */

    a->write();            // 这就是你所说的 Error:不能访问protected函数。  因为这是 外部分的访问

}

不知道这么说 楼主 明白点没?
个人的观点啊,我觉得是这样的

因为call()函数是其成员函数,所以能访问类的保护成员于私有成员。其实protected保护成员真正用武之地是在类继承中,保护成员属性private于public中,使用protected继承能使派生类能够访问基类protected成员,但是外界不能访问。。。
6楼很强大.
楼上也不赖哈哈
引用 3 楼 rejoice914 的回复:
protected 
权限是基类的内部和继承类的内部! 
外面是不可以的!

正确
protected 限定为只有定义类时的内部成员(成员函数)可以访问或者是此类的派生类中的成员函数

但用此类来申明的对象不可以访问或者其派生类来申明的对象也不可以访问

即类的定义部分为类的内部

而类申明的对象为类的外部
引用 8 楼 gongyue1983 的回复:
那么我得出这么一个结论 不知道正确不:

protected 函数不能在外部调用,这个是大家都确认的。
而在内部是可以调用的,无论是直接调用如:
void A::call()
{
write();
}

还是通过实例 如:
void A::call()
{
A* a = new B;
a->write();

A _a;
_a.write();

}

都是可以的。只要write()出现在内部。

这样解释对吗?

我想LZ的真正的疑问是B的实例与A的指针的问题
可惜,在编译期,是不知道是B的实例的
到了运行时候才知道
所以可以编译通过
因为在call()里,是一个类的一个成员函数去访问保护成员
你在main函数里面你调用就是类外访问所以出错啊
d
呵呵,建议看一下public protect private 的子类的访问权限
2楼说得很对。
找本书先好好看看吧,这太基础了,恐怕连课后习题都算不上。
先把基本的看懂了再回来就会了...
引用 1 楼 chen_de_sheng 的回复:
protected表示这个成员可以被类内部成员访问 
也可以被派生类内部访问 
但是不能在类外访问

完全同意此贴
这就是访问权限的问题了嘛!
找本C++的书看看吧,这样的问题是讲C++的书就应该会讲的!
继承的时候被定义为保护的成员只能被本类以及子类的成员所访问,这是规定!
如果你想在别的地方访问,要么把这个类作为你想调用函数那个类的友元,要么再类中写个公共的方法来调用哪个受保护的成员!这样间接的也可以,但是直接调用不可以!
引用 1 楼 chen_de_sheng 的回复:
protected表示这个成员可以被类内部成员访问 
也可以被派生类内部访问 
但是不能在类外访问

up
慢慢学习

PS: 
我的目标是 ----> 

^_^
内部是可以访问的,内部连私有变量都可以访问

要不然,拷贝构造函数怎么办
在类的外部是肯定不能访问protected的
但基类好像可以访问子类的protected
up
都解释得很清楚了,up!
protected和private一样只能在本类中被访问
只是protected可以被继承
引用楼主 gongyue1983 的帖子:
//A.h 
class A 

  public: 
        A(); 
        virtual ~A(); 
void call(); 
  protected: 
        virtual void write(); 
}; 

//A.cpp 
#include "A.h" 
#include <stdio.h> 

A::A(){} 
A::~A(){} 
void A::write() 

    printf("A::write"); 


void A::call() 

    A* a = new B; 
    a->write(); 


//B.h 
#include "A.h" 
class B:public A 

      public: 
        B(); 
        virtual ~B(…

楼主,我很想知道,类A中的红色部分,你怎么通过编译的。
类A和类B是一个典型依赖环关系,很想到楼主是如何解开这个环的?

回楼主:派生类中调用基类的protected函数,和调用自己的private函数是一样的,当然不能再main里调用了。(再不清楚看书吧。。。)


回37楼,楼主的代码基本是可以编译的,除了少几个分号。这里类A和类B并没有形成依赖环,依赖部分在类A对类B的依赖在cpp文件中,不存在问题
及时形成依赖环,只需要在类A的声明前面(A.h中)加上这么一行就行了 

class B;
引用 38 楼 matrixcl 的回复:
回楼主:派生类中调用基类的protected函数,和调用自己的private函数是一样的,当然不能再main里调用了。(再不清楚看书吧。。。) 


回37楼,楼主的代码基本是可以编译的,除了少几个分号。这里类A和类B并没有形成依赖环,依赖部分在类A对类B的依赖在cpp文件中,不存在问题 
及时形成依赖环,只需要在类A的声明前面(A.h中)加上这么一行就行了 

class B; 


这位大哥,你看清楚了,
void A::call() 

    A* a = new B; 
    a->write(); 

这段代码,我很想知道怎么通过。
前置声明,最多可以定义指针,哪能创建对象呢?
更别说了vptr了.
在类中,所有的自己对象都能访问自己的所有成员变量和成员方法
最典型的就是拷贝构造函数
class A
{
public:
    A(const A& a)
   {
       i = a.i;
   }

private:
    int i;
};
相信大家看到这样的代码不是一两次了吧,这就是我说的,所有的对象在自己的类中能访问自己类的所有成员方法和成员变量的意思,
同理,楼主的问题就是在这里
在类A中随让a是一个对象,但是它是在自己的类中,所以可以访问类A的成员及函数,而在main()函数中,A的对象就不能访问除public的其他访问权限的方法和变量
protected: 
       virtual void write(); //应该就可以了
private 权限:能够访问的有二类:1.自己类本身,2.在类中申明的友员函数,友员类.
protected 权限:在private的权限上,加上可以被子类访问.
public  权限 : 公开的接口,任何函数都可以.
protected的成员 在被私有继承之后,会变成prviate型的
                  在被公有继承后,仍然保持protected
1楼的正解
你提供一个成员函数 get出来不就可以了 
aaa
引用楼主 gongyue1983 的帖子:
//A.h 
class A 

  public: 
        A(); 
        virtual ~A(); 
void call(); 
  protected: 
        virtual void write(); 
}; 

//A.cpp 
#include "A.h" 
#include <stdio.h> 

A::A(){} 
A::~A(){} 
void A::write() 

    printf("A::write"); 


void A::call() 

    A* a = new B; 
    a->write(); 


//B.h 
#include "A.h" 
class B:public A 

      public: 


正解。。。
基类内部和直接派生类的内部都可以访问
6楼正解,偶也是菜鸟,学习了。看书终觉浅,不防找个C++开发的工作实际动手练。

在Asp中,怎么才能将数组传入函数里 请教高手!!!使用MSComm控件将握手协议设置为RTS/CTS模式,对应的DCB的参数是怎样? 问个读文件的问题,真麻烦 有一个表,我希望通过不同的条件 提取 同一编号的最后一个日期的数据 怎样通过一个参数控制存储过程返回的记录数????? 求一存储过程,请高手们赐教(本人以前未接触过存储过程) 看看这一句SQL语句哪里有错? 如何把System.Drawing.Color 转化为16进制的数值(字符串) 如何屏蔽console 求助!我在applet类里实例化一个类并启动另外一个线程运行,实例化的这个类调用一个配置文件subxcribe.config,运行是提示java.io.FileNotFo 有什么工具可把把 *.avi 格式的动画修改里面的内容? Service Unavailable 问题(加急,在线等) 晕了,报了错误也照用不误,程序正常运行!晕??????? 怎样找带环单链表环开始的结点.. 注册表 最后50分了,求解jndi连接串的区别! accept为何不阻塞? 怎样写字符间的循环语句? 有关附件的问题,帮帮忙了,急 关于style=\"position:absolute;\"导致的问题 现在有3g左右的文本文件,需要用java的流来读,用什么样的流能高效的读 用能js改变来完成吗? ping 得通,ODBC连不上,急死 如何让IE一启动,WEB窗口就最大化! 如何用验证控件来验证大量WEB控件是否填写数据,或者用其他方法验证? 登录界面想要记住用户名,不用数据库,怎么记住? 如何获得前一记录??? 无良版主不下台,水园难平民愤! eclipse调试不能高亮显示 给控件添加一个提示框, 如何实现象Excel风格的注释效果?