C++ 保护的变量不被继承

标签 c++ class inheritance member protected

我已经编写了一些代码来计算 RSA 密码算法。该程序使用类和继承,因为我想为多个用户计算公钥和私钥。有父类 rsa 和子类 public_keyprivate_key

编译下面的代码时,我遇到了很多错误。所有这些都是关于派生类在其各自的构造函数中没有可用字段的(请参阅代码下方的错误消息)。但是,这些变量是在父类中使用 protected 访问修饰符定义的,因此子类应该可以访问它们。

旁注:我在两个子类中都有函数 key,但我认为将它放在父类中一次会更好,对吗?

代码如下:

#include <iostream>
#include <math.h>

using namespace std;

class rsa
{
protected:
    int p, q, d, m, n, f, e, c, end, k;

public:
    rsa() : n(0), e(0), c(0), k(0), end(0), f(0)
    { }

    void set(int , int , int, int);

    int key()
    {
        n = p * q;
        f = (p - 1) * (q - 1);

        for (k; end < 1; k++)
        {
            if ((1 + k * f) % d == 0) 
            {
                end = 2;
                e = (1 + k * f) / d;
            }
        }

        c = int(pow(m, e)) % n;

        return c;
    }
};

void rsa::set(int p_, int q_, int d_, int m_)
{
    p = p_;
    q = q_;
    d = d_;
    m = m_;
}

class public_key : public rsa
{
public:
    public_key() : n(0), e(0), c(0), k(0), end(0), f(0)
    { }
};

class private_key : public rsa
{
public:
    private_key() : n(0), e(0), c(0), k(0), end(0), f(0)
    { }
};

int main()
{
    public_key usr1, usr2;
    private_key usr1r, usr2r;

    usr1.set(11, 5, 23, 9);
    usr2.set(13, 7, 97, 6);
    usr1r.set(17, 7, 51, 8);
    usr2r.set(11, 17, 51, 4);

    cout << "Public key of user 1: " << usr1.key() << endl;
    cout << "Public key o user 2: " << usr2.key() << endl;

    cin.get();

    return 0;
}

错误之一:

error: class ‘private_key’ does not have any field named ‘e’
   private_key () : n(0), e(0), c(0), k(0), end(0), f(0) {} ;

所有其他错误都相同,但字段名称更改。

最佳答案

该错误与rsa 类成员的访问级别无关。即使您将这些成员声明为 public,您仍然会收到错误消息。问题是派生类的初始化列表仅在其自身的上下文中运行,您无权访问基类成员。

但是,您可以在派生类构造函数的主体中访问基类成员(publicprotected)。例如:

class public_key : public rsa
{
public:
    public_key()
    {
        n = 0;
        e = 0;
        c = 0;
        k = 0;
        end = 0;
        f = 0;
    }
};

class private_key : public rsa
{
public:
    private_key()
    {
        n = 0;
        e = 0;
        c = 0;
        k = 0;
        end = 0;
        f = 0;
    }
};

虽然上面的代码使用赋值而不是初始化,但它在底层为基本类型做了完全相同的事情,所有这些成员都是。

不过,尽管上面的代码有效,但它是做你想做的事情的错误方法。您已经为 rsa 类编写了构造函数,因此避免重复代码的一种方法是从初始化列表中调用现有的构造函数。

class public_key : public rsa
{
public:
    public_key() : rsa()
    { }
};

class private_key : public rsa
{
public:
    private_key() : rsa()
    { }
};

但是请注意 rsa() 是默认构造函数(因为它没有参数)所以它会被派生类的任何构造函数自动调用(除非您指定其他一些 rsa 初始化列表中的构造函数)。

class public_key : public rsa
{
public:
    public_key()
    { } // rsa() will be called automatically
};

class private_key : public rsa
{
public:
    private_key()
    { } // rsa() will be called automatically
};

但现在您的派生类具有空的默认构造函数,您甚至不需要它们(除非您计划添加更多逻辑)。

class public_key : public rsa
{
public:
    // rsa() will still be called automatically when declaring an instance of public_key
};

class private_key : public rsa
{
public:
    // rsa() will still be called automatically when declaring an instance of private_key 
};

关于 key() 函数的旁注,如果 key() 的实现在两个子类中是相同的,那么是的,您只需要它一次在父类。你应该始终避免代码重复,所以即使 key() 的一小部分需要为每个子类定制,你最好在基类中编写一个虚函数来 key( ) 可以作为计算的一部分调用。然后,在每个子类中,用任何必要的特化覆盖虚函数。这样所有的共享代码都可以保留在父类的key()函数中。

关于C++ 保护的变量不被继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23598199/

相关文章:

JavaSsist:toBytecode()抛出异常java.lang.RuntimeException:remaper.by.moofMonkey.Main类被卡住但他没有被卡住

c++ - 如何将 "struct Node"转换为 "class Node"?

java - 使用 EL 向下转换

c++ - 为什么 C++ 可执行文件在与较新的 libstdc++.so 链接时运行速度如此之快?

c++ - 我如何知道 USB 设备是否已在使用中?

c++ - GDB:[无可用资源]

c++ - 处理 3D 数组的边角情况的方法

java - java中的类 `Class`和类 `Type`有什么区别?

inheritance - 运行时的 Fortran TYPE 继承(由用户声明)

c++ - 多重继承中没有匹配函数