C++受保护的变量不是继承的

Moh*_*med 0 c++ inheritance class protected member

我编写了一些代码来计算RSA加密算法.该程序使用类和继承,因为我想为多个用户计算公钥和私钥.有一个父类rsa和子类public_key和private_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;
}
Run Code Online (Sandbox Code Playgroud)

其中一个错误:

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) {} ;
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*iel 5

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

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

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

虽然上面的代码使用了赋值而不是初始化,但是对于原始类型而言它完全相同,所有这些成员都是如此.

尽管如此,虽然上面的代码有效,但这是做错的方式.您已经为类编写了构造函数rsa,因此避免重复代码的一种方法是从初始化列表中调用现有构造函数.

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

class private_key : public rsa
{
public:
    private_key() : rsa()
    { }
};
Run Code Online (Sandbox Code Playgroud)

但是请注意,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
};
Run Code Online (Sandbox Code Playgroud)

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

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 
};
Run Code Online (Sandbox Code Playgroud)

关于key()函数的附注,如果key()两个子类中的实现相同,则是,在父类中只需要一次.你应该总是避免代码重复因此,即使一小部分key()需要进行自定义每个子类中,你最好写在基类,虚函数key()可以调用作为计算的一部分.然后,在每个子类中,使用任何必要的专门化覆盖虚函数.因此,所有共享代码都可以保留在父类key()函数中.


Vla*_*cow 5

根据 C++ 标准(12.6.2 初始化基数和成员,第 #2 段)

\n\n
\n

除非 mem-initializer-id 命名构造函数\xe2\x80\x99s 类、构造函数\xe2\x80\x99s 类的\n 非静态数据成员、或者该类的直接或\n 虚拟基类,否则mem-initializer 格式错误。

\n
\n\n

因此,程序中派生类的内存初始化器格式不正确,并且编译器会发出错误。

\n\n

它是应该初始化其数据成员的基类构造函数。

\n\n

定义类的构造函数没有任何意义,例如 public_key ,如下所示

\n\n
public_key () : n(0), e(0), c(0), k(0), end(0), f(0) {} ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

因为首先会调用基类的构造函数

\n\n
rsa () : n(0), e(0), c(0), k(0), end(0), f(0) {};\n
Run Code Online (Sandbox Code Playgroud)\n\n

它将初始化数据成员。

\n\n

所以写就够了

\n\n
rsa () {}\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者

\n\n
rsa () = default;\n
Run Code Online (Sandbox Code Playgroud)\n