公共继承中的公共方法在 C++ 中变为私有方法

Public method in public inheritance becomes private in C++

提问人:Alessandro 提问时间:8/20/2023 最后编辑:ChrisAlessandro 更新时间:8/20/2023 访问量:85

问:

我有一个带有公共方法的基类,但是当我尝试从从基类公开继承的派生类调用它时,它就变成了私有的。这怎么可能?公共继承难道不意味着公共方法被公开吗?

这些是基类,我所指的方法就是方法r()

#define POTENTIALS_HPP

#include <cmath>
#include "Matrix.hpp"
#include "Physics_constants.hpp"
#include "PotentialData.hpp"

class Potential {
public:
    Potential() {}
    Potential(int l, int s, int j, double Mmu) : m_l(l), m_s(s), m_j(j),
        m_Mmu(Mmu){}
    virtual void setL(int) = 0;
    virtual void setS(int) = 0;
    virtual void setJ(int) = 0;
    virtual void setR(double) = 0;
    ushort l() const {return m_l;}
    ushort s() const {return m_s;}
    ushort j() const {return m_j;}
    double r() const {return m_r;}
    double Mr() const {return m_Mmu;}
    ~Potential() {}

    virtual Matrix<double> operator () () const = 0;
    virtual Matrix<double> operator () (double) = 0;
    Matrix<double> Veff() const {
        if (m_l==0 || m_r == 0)
            return (*this)();
        Matrix<double> p = (*this)();
        Matrix<double> L(p.cols());
        for (uint i=0; i<L.cols(); i++)
            L[i][i] = (m_l+2*i)*(m_l+2*i+1);
        L = L*(pow(Physics::Nuclear::hc,2)/(2*m_Mmu*m_r*m_r));
        std::cout << m_Mmu << "  " << m_r << std::endl;
        std::cout << p-L << std::endl;
        abort();
        return p-L;
    }
    Matrix<double> Veff(double r) {
        setR(r);
        return Veff();
    }

protected:
    ushort m_l;
    ushort m_s;
    ushort m_j;
    double m_r;
    double m_Mmu;
};

#endif // POTENTIALS_HPP

这是派生类

#ifndef ALPHAD_POTENTIAL_HAMMACHE_HPP
#define ALPHAD_POTENTIAL_HAMMACHE_HPP

#include "Physics_constants.hpp"
#include "Potentials.hpp"
#include <cmath>

class HammachePotential : public Potential {
public:
    HammachePotential() { m_s = 1; m_Mmu = PotentialData::Hammache::Mr;}
    HammachePotential(int l, int j) : Potential(l,1,j,PotentialData::Hammache::Mr) {
        if (l==0)
            V0 = 60.712;
        else
            V0 = 56.7;
        setLS2(l,s,j);
    }

    void setS(int) override {m_s=1;}

    void setL(int l) override {
        this->l = l;

        if (l==0)
            V0 = 60.712;
        else
            V0 = 56.7;
        setLS2(l,s,j);
    }
    void setJ(int j) override {
        this->j = j;
        setLS2(l,s,j);
    }
    void setR(double r) override {
        if (r==0)
            return;
        this->r = r;

        EXPR = expr(r);
        EXPRM1 = exprm1(EXPR);
    }

    std::tuple<int,int,int,double> getInfo() const {
        return {l,s,j,r};
    }

    double getVcDepth() const {
        return V0;
    }


    Matrix<double> operator () () const {
        if (r==0)
            return Matrix<double>(1);
        double Vc = -V0*EXPRM1;
        double Ve = Vem(r);
        double Vso= VSO*EXPR*std::pow(EXPRM1,2)/r;
        Matrix<double> ret(1);
        ret[0][0] = Vc+Ve+Vso;
        return ret;
    }

    Matrix<double> operator () (double r) {
        if (r==0)
            return Matrix<double>(1);
        setR(r);
        double Vc = -V0*EXPRM1;
        double Ve = Vem(r);
        double Vso= VSO*EXPR*std::pow(EXPRM1,2)/r;
        Matrix<double> ret(1);
        ret[0][0] = Vc+Ve+Vso;
        return ret;
    }



private:
    const double a =    0.65; //fm
    const double r0 =   1.25; //fm
    const double R =    r0*std::pow(6.,1./3); //fm
    const double l2 =   4.; //fm^2 -> lambda^2
    int l = 0;
    const int s = 1;
    int j = 1;
    int LS2;
    double V0;
    const double V1 = 2.4; //MeV
    const double coul = 2*Physics::alpha*Physics::Nuclear::hc;
    const double VSOfac0 = -V1*l2/a;
    double VSO;
    double r;
    double EXPR;
    double EXPRM1;

private:
    inline void setLS2(int l, int s, int j) {
        LS2 = j*(j+1) - l*(l+1) - s*(s+1);
        VSO = VSOfac0*LS2;
    }
    inline double Vem(double r) const {
        if (r<=R)
            return coul*(3-std::pow(r/R,2))/(2*R);
        else
            return coul/r;
    }
    inline double expr(double r) const {
        return std::exp( (r-R)/a );
    }
    inline double exprm1 (double expr) const {
        return 1.0/(1.0 + expr);
    }
};
#endif // ALPHAD_POTENTIAL_HAMMACHE_HPP

编辑: 编译器输出为

...main.cpp:184: error: ‘double HammachePotential::r’ is private within this context
...main.cpp:184:30: error: ‘double HammachePotential::r’ is private within this context
  184 |             std::cout << pot.r() << std::endl;
      |                              ^```

The error is also for the methods `l()`, `s()`, `j()`, but not `Mr()`.

I will soon try to reproduce a minimal example of it and see how it goes. I am sorry, but I am new asking questions here.
C++ 虚拟继承 公共方法

评论

2赞 Some programmer dude 8/20/2023
请尝试创建一个最小的可重复示例来向我们展示。强调最小的部分。并包含所示示例中完整和完整的构建日志的复制粘贴(作为文本)。
1赞 273K 8/20/2023
我尝试从一个派生类调用它,该派生类公开继承自它成为私有的基类。最好发布准确和完整的编译器错误消息,而不是描述它。
2赞 273K 8/20/2023
我所指的方法就是 r() 方法。所以大多数其他代码是无关紧要的?请看一下如何制作一个最小的可重复示例
2赞 273K 8/20/2023
顺便说一句,在显示的大代码中从未调用过。r()
1赞 Chris 8/20/2023
@Alan,请不要完全重写其他用户的问题。

答:

4赞 Alan Birtles 8/20/2023 #1

您有一个私有成员变量,该变量在其中隐藏了 中的方法。确保检查编译器的完整错误消息,GCC 至少给出了足够的提示来解决这个问题: https://godbolt.org/z/bbv5v9fehrHammachePotentialPotential

<source>:188:7: error: 'double HammachePotential::r' is private within this context
  188 |     a.r();
      |       ^
<source>:162:12: note: declared private here
  162 |     double r;
      |            ^
<source>:188:8: error: expression cannot be used as a function
  188 |     a.r();
      |     ~~~^~