当前位置:首页 » 文件传输 » 怎么访问私有虚函数
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

怎么访问私有虚函数

发布时间: 2022-05-10 00:56:50

㈠ c++有趣现象:private的成员函数可以在类的外部调用

发现新大陆了呵呵,不错,但是,它并不是C++的缺陷或是被设计者所忽视的问题。

当我们使用虚函数的时候,它的访问规则是在声明的时候被确定的,而不是在被“子类重写”(overridden)的时候,虚函数的访问规则不会受到来自被重写的子类函数的影响,更进一步说,当某个对象A的引用B(特指间接访问)用来调用该对象的虚函数时,对于该对象A的一切声明信息,都取决于该对象的引用B,而不是这个引用所引用的对象A。

C++标准里有对该问题的具体说明:当一个子类函数通过基类的指针调用时,访问权限取决于基类对该函数的声明。

参考C++ Standard ISO/IEC 14882:2003(E) 第11.6节:

11.6 Access to virtual functions [class.access.virt]

The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it. [Example:
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); //OK: B::f() is public,
// D::f() is invoked
pd->f(); //error: D::f() is private
}
—end example]

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

至少我们在程序编译时无法获知这个指针的值,它会指向何种位置。

经验:private仅仅是一个访问限定符,它只限定函数和数据不能被“直接”访问,而不担保这些函数和数据会被通过其他方法间接地访问到,在成员函数中返回一个类私有数据成员的引用也是这个道理。

另外,如果不是特殊的需要,一般来说,这并不是一个好的设计,有点自找麻烦的味道!

㈡ 子类里覆盖父类虚函数的后的成员函数,能不能访问父类私有成员,,,,

私有成员是不能被子类访问,无论是子类中的什么函数。

public就是外面能访问,
private就是外面不能访问。
这是访问控制的。

㈢ C++纯虚函数有受保护的虚函数a和私有成员变量,其子类实现了a函数,a如何访问基类的私有成员变量

除非基类为子类再提供非私有的getter/setter或者把子类声明为友元类或者直接改为非私有成员变量, 否则无法访问

㈣ c++ 如何访问抽象类的私有成员

根据别人的回答和你的追问,我发现了问题所在。
你的题目要求是数据成员定义的为私有,而不是成员函数定义为私有啊~~

数据成员和成员函数是不一样的啊。
若数据成员为私有,定义一个公有成员函数T getMember() const{return member;}就可以让别人获得这个私有数据成员啦。
总之你的成员函数要定义为公有的。除非是你的类自己用的间接函数(仅仅被类的其他成员函数调用)。否则定义为私有,其他对象不能访问,就没有意义了

㈤ C++中,基类的虚函数的访问权限是private时,它的派生类对虚函数的访问权限到底是怎样的

B *bp指针时,只能按照类B的接口规则来访问,你在D1里面更改了访问权限,父类是无法知晓子类的更改的,你这个做法叫做隐藏了接口。一般的代码编写中很少使用你这个做法。

B类的b方法是private的,所以main函数无权访问。
D1类的a方法覆盖了父类的方法a,权限已经更改为private,所以main无法直接使用D1的实例来访问a方法。
这些都是语法层面的东西而已。

还有一点,这种随心所欲的代码风格设计在工作中是需要避免的。

回到这个问题:
基类的虚函数的访问权限是private时,它的派生类对虚函数的访问权限到底是怎样?

答案:子类无法派生和继承父类的private成员和方法。父类的private只属于父类所有,只有父类和父类的友元才能访问父类的private成员和方法。

㈥ C++ 虚函数使用以及继承的问题 急~

#include <iostream>
#define PI 3.14
using namespace std;
class container
{
public:
container(int radius=0){
this->radius = radius;/*赋值给类的成员变量*/
}
virtual void Square()=0;
virtual void Volume()=0;
int GetRadius(){return radius;} /*给私有成员变量提供一个访问的函数*/
/*要想修改就提供一个void SetRadius(int radius)的函数*/
private:
int radius;
};
class cube:public container
{
public:
cube(int radius1):container(radius1){}
virtual void Square()
{
/*基类的私有成员在这里无法之间反问,可通过基类的成员函数访问,下面凡事访问radius都通过
GetRadius()来访问*/
square1=4*PI*GetRadius()*GetRadius();
cout<<"the cube's square is:"<<square1<<endl;
}
virtual void Volume()
{
volume1=(4.0/3)*PI*GetRadius()*GetRadius()*GetRadius();/*4/3等于1了,要写成4.0/3才对 */
cout<<"the cube's volume is:"<<volume1<<endl; /*这里应该是volume1*/
}
private:
double square1,volume1;
};
class sphere:public container
{
public:
sphere(int radius1):container(radius1){}
virtual void Square()
{
square2=6*GetRadius()*GetRadius();
cout<<"the sphere's square is:"<<square2<<endl;
}
virtual void Volume()
{
volume2=GetRadius()*GetRadius()*GetRadius();
cout<<"the sphere's volume is:"<<volume2<<endl;
}
private:
double square2,volume2;
};
class cylinder:public container
{
public:
cylinder(int radius1):container(radius1){}
virtual void Square()
{
cout<<"please input the cylinder's height=";
cin>>height;
square3=2*PI*GetRadius()*GetRadius()+2*PI*GetRadius()*height;
cout<<"the cylinder's square is:"<<square3<<endl;
}
virtual void Volume()
{
volume3=PI*GetRadius()*GetRadius()*height;
cout<<"the cylinder's volume is:"<<volume3<<endl;
}
private:
double square3,volume3;
int height;
};
int main()
{
//container container1;
int a;
cout<<"Please input a radius=";
cin>>a;
cube cube1(a);
sphere sphere1(a);
cylinder cylinder1(a);
cube1.Volume();
cube1.Square();
sphere1.Volume();
sphere1.Square();
cylinder1.Square();
cylinder1.Volume();
return 0;
}

㈦ 高分 c++ typedef 访问基类的私有虚函数

//使用typedef来定义一个函数指针,可以参阅相关资料
typedefvoid(*Fun)(void);
voidmain()
{
Bb;//一个子类的对象
//这里如果不用typedef的话就应该是
//void(*pFun)(void);
FunpFun;
for(inti=0;i<3;i++)
{
//其实是得到b的地址,但是不能直接写成intaddr=&b;这样编译器会报错的
//所以才有了下面的两个*
intaddr=*(int*)&b;
//现在addr变成了存储b开始的地址的一个int型变量,所以我们还需要:
//classB的布局为:B的vtable,函数h的地址
//而B的vtable展开就是:函数g的地址,函数f的地址
//所以B的布局展开就是:函数g(被B覆写)的地址,函数f(A的f)的地址,函数h的地址
//每个地址占4个字节
//那么b+0为g的地址,b+4为f的地址,b+8为h的地址
//但是为什么循环里是按照1递增呢?因为上面的情况是按照char类型递增的
//根据C的寻址规则,增加一个int其实就是增加了4个字节
//所以我们有了(int*)addr,这是说按照int型的字长来增加寻址字节数
//经过上面的分析,可以知道:
//((int*)*(int*)(&b)+0)其实就是g的地址
//((int*)*(int*)(&b)+1)其实就是f的地址
//((int*)*(int*)(&b)+2)其实就是h的地址
//那么它终究还是一个地址,于是前面再加了一个*,就是函数的内容
pFun=(Fun)*((int*)*(int*)(&b)+i);
//然后开始运行这个函数
pFun();
}
}

vtable很复杂,可以参看C++对象模型那本书,如果只是想现在大致了解一下,可以参看下面的网址

http://blog.csdn.net/haoel/article/details/1948051/

我讲的也可能不对,不可尽信。