【问题标题】:How do I make an externally defined function available in a C++ class?如何使外部定义的函数在 C++ 类中可用?
【发布时间】:2019-11-12 23:51:58
【问题描述】:

我有一个与 Armadillo 包一起使用的类来创建特定类型的矩阵。我在调试它时遇到了麻烦,所以我想使用我编写的一个名为Matlab_Print 的函数。它存在于自己的 .h.cpp 文件中,并在我的代码中使用。类和函数都可以完美运行,但我似乎无法将它们结合起来。

我在类定义之前和之后都在SU3.h 中尝试过#include "Matlab_Print"。我真的不想让函数成为类函数,因为我经常使用Matlab_Print。我确实有一个解决方法,但它很不方便,而且无论如何我认为这是一个学习机会。

在调用SU3 构造函数时,我使用try 捕获错误消息,我得到以下信息:

错误:Mat::init():大小是固定的,因此无法更改

main.cpp

#include "pch.h"
#include <new>
#include <exception>
#include "SU3.h"

int main(int argc, char *argv[])
{
    int icount { 0 };
    SU3 *su3[10];

    try
    {
        for (icount = 0; icount < 10; icount++)
        {
            su3[icount] = new SU3(0.1);
        }
    }
    catch (int param) { cout << "Function " << __func__ << " int " << param << " exception in memory allocation for su3" << std::endl; exit(1); }
    catch (char param) { cout << "Function " << __func__ << " char " << param << " exception in memory allocation for su3" << std::endl; exit(1); }
    catch (...) { cout << "Function " << __func__ << " exception in memory allocation for su3" << std::endl; exit(1); }

    return 0;
}
SU3.h

#include "pch.h"
#include "SU3.h"
#include <armadillo>
#include "Matlab_Print.h"

class SU3
{
public:
    arma::Mat<cx_double>::fixed<3, 3> *X;
    SU3(const double epsilon);
};
SU3.cpp

SU3::SU3(const double epsilon)  // simplifed so that epsilon plays no role
{
    const std::complex<double>    o{ 1.0 , 0.0 };    // complex 1
    const std::complex<double>    z{ 0.0 , 1.0 };    // complex 0

    X = new arma::Mat<cx_double>::fixed<3, 3>{ fill::zeros }; //// solution to problem: define and initialize pointer ////

    *X =    {   { o, z, z},
            { z, o, z},
            { z, z, o} };

    Matlab_Print(*X, "SU3");        // this is the line I wish to use
}
Matlab_Print.h

#include <armadillo>
#include <complex>

void Matlab_Print(arma::Mat<cx_double>::fixed<3, 3> Matrix, std::string T);
Matlab_Print.cpp

#include "pch.h"
#include "Matlab_Print.h"

void Matlab_Print(arma::Mat<cx_double>::fixed<3, 3> Matrix, std::string T)
{
    std::cout << std::endl;

    std::cout << "RE = [" << std::real(Matrix(0, 0)) << "   " << std::real(Matrix(0, 1)) << "   " << std::real(Matrix(0, 2)) << ";   ";
    std::cout << std::real(Matrix(1, 0)) << "   " << std::real(Matrix(1, 1)) << "   " << std::real(Matrix(1, 2)) << ";   ";
    std::cout << std::real(Matrix(2, 0)) << "   " << std::real(Matrix(2, 1)) << "   " << std::real(Matrix(2, 2)) << "];  " << std::endl;

    std::cout << "IM = [" << std::imag(Matrix(0, 0)) << "   " << std::imag(Matrix(0, 1)) << "   " << std::imag(Matrix(0, 2)) << ";   ";
    std::cout << std::imag(Matrix(1, 0)) << "   " << std::imag(Matrix(1, 1)) << "   " << std::imag(Matrix(1, 2)) << ";   ";
    std::cout << std::imag(Matrix(2, 0)) << "   " << std::imag(Matrix(2, 1)) << "   " << std::imag(Matrix(2, 2)) << "];  " << std::endl;

    std::cout << T << " = RE + 1i*IM;" << std::endl;
}

感谢您的耐心等待。我希望这就是您需要的所有信息。

【问题讨论】:

  • 你是对的,我的错。我想构造一个矩阵 X,然后希望在运行时以 MATLAB 格式打印出来。如果我在 SU3.h 中 #include "Print_Matlab" 程序编译成功,但会出现我上面指出的运行时错误。如果我删除#include 和对 Print_Matlab 的函数调用(见下文),它会编译并完美运行(好吧,它完美地给了我错误的答案:) 无论如何)。
  • 我希望这可以澄清问题而不会过于简单
  • 一次只问一个问题,并提供所有必需的信息,以便我们能够为您提供帮助。正如所写的那样,我们缺少太多信息,无法真正帮助您,除非可能会做出与您的实际问题相关或不相关的任意猜测。例如,您确定应该通过副本将参数传递给 print 函数吗?我们无法真正分辨,因为我们没有部分代码。另外,如果您在调用构造函数时遇到错误,请告诉我们在哪一行。
  • 我希望我最近的编辑能够澄清编码问题。这编译得很好,但给了我上面显示的运行时错误。如果我从 SU3.h 和 SU3.cpp 中删除对 Matlab_Print 的所有引用,它工作正常。不幸的是,没有给出行号作为参考,但我通过在 main.cpp 的循环中打印 icount 知道 icount = 0 会发生错误,因此它在第一个构造函数调用时被轰炸。
  • 您在 SU3::SU3 中有未定义的行为,因为您在没有先初始化的情况下取消引用 X

标签: c++ function class


【解决方案1】:

正如@uneven_mark 所指出的,您在SU3::SU3 中有未定义的行为,因为您在没有先初始化的情况下取消引用X。你可能不想要一个指针。

注意你不需要需要new 来创建类类型的对象。

class SU3
{
public:
    arma::Mat<cx_double>::fixed<3, 3> X;
    SU3(const double epsilon);
};

using namespace std::literals::complex_literals;

SU3::SU3(const double epsilon)
  : X({ { 1, 1i, 1i },
        { 1i, 1, 1i },
        { 1i, 1i, 1 } }) // prefer member initialisers over assingments
{
    Matlab_Print(X, "SU3");
}

【讨论】:

  • 非常优雅的解决方案,我也会在代码中尝试一下。
猜你喜欢
  • 2011-04-30
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多