英文:
Illegal call of non-static member function - C++
问题
我正在尝试在C++中实现一个接口,但当我尝试在派生类中使用一些方法时,我遇到了标题中的问题。
代码的思路如下:
// ClassHeader.h
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
namespace b {
struct mainObj {
virtual ~mainObj(void) {}
virtual double met(const std::vector<double>& vals) const = 0;
};
class Interface {
public:
Interface(size_t m, const std::vector<double>& tt);
protected:
struct OriginalObj;
size_t _m;
std::vector<double> _tt;
private:
virtual boost::shared_ptr<OriginalObj> make_obj(size_t M, const std::vector<double>& T) const = 0;
virtual const std::vector<double> method1(size_t M, const std::vector<double>& vals) = 0;
};
namespace a {
class Child1 : public Interface {
public:
Child1(size_t m, const std::vector<double>& tt);
private:
struct obj1;
boost::shared_ptr<OriginalObj> make_obj(size_t M, const std::vector<double>& T) const override;
const std::vector<double> method1(size_t M, const std::vector<double>& vals) override;
};
} // namespace a
} // namespace b
// ClassHeader.cpp
#include "ClassHeader.h"
namespace b {
Interface::Interface(size_t m, const std::vector<double>& tt)
: _m(m), _tt(tt) {}
struct Interface::OriginalObj : public mainObj {
OriginalObj(size_t n, const std::vector<double>& t)
: _n(n),_t(t) {}
size_t _n;
std::vector<double> _t;
};
namespace a {
const std::vector<double> Child1::method1(size_t M, const std::vector<double>& vals) {
return { static_cast<double>(M), vals[0] };
}
struct Child1::obj1 : public Interface::OriginalObj {
using Interface::OriginalObj::OriginalObj;
Child1* owner;
double met(const std::vector<double>& vals) const override {
std::vector<double> c = owner->method1(_n, vals);
return c[0];
}
};
Child1::Child1(size_t m, const std::vector<double>& tt)
:Interface(m, tt) {
obj1 o1(m, tt);
o1.owner = this;
}
auto Child1::make_obj(size_t M, const std::vector<double>& T) const -> boost::shared_ptr<OriginalObj> {
return boost::shared_ptr<OriginalObj>{new Child1::obj1(M, T)};
}
} // namespace a
} // namespace b
我知道我在没有在对象上调用它的情况下使用它(例如 c1.method1(...)
),但我认为由于它是一个类方法,这在某种程度上是暗示的。我面临的另一个问题是,我无法将该方法设为静态,因为它是虚拟的。
请问有谁能帮我理解我做错了什么以及如何解决这个问题吗?
提前感谢!
我更改了代码以重现错误。现在我在与实际代码中完全相同的位置遇到了完全相同的错误。希望这能帮到您找出我做错了什么。
再次感谢!
英文:
I'm trying to implement an interface in C++ but I get stuck on the problem in the title when I try to use some methods within the derived classes.
The idea of the code is as follows.
// ClassHeader.h
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
namespace b
{
struct mainObj
{
virtual ~mainObj(void) {}
virtual double met(const std::vector<double>& vals) const = 0;
};
class Interface
{
public:
Interface(size_t m, const std::vector<double>& tt);
protected:
struct OriginalObj;
size_t _m;
std::vector<double> _tt;
private:
virtual boost::shared_ptr<OriginalObj> make_obj(size_t M, const std::vector<double>& T) const = 0;
virtual const std::vector<double> method1(size_t M, const std::vector<double>& vals) = 0;
};
namespace a {
class Child1 : public Interface
{
public:
// inherit constructor
// using Interface::Interface;
Child1(size_t m, const std::vector<double>& tt);
private:
struct obj1;
boost::shared_ptr<OriginalObj> make_obj(size_t M, const std::vector<double>& T) const override;
const std::vector<double> method1(size_t M, const std::vector<double>& vals) override;
};
} // namespace a
} // namespace b
// ClassHeader.cpp
#include "ClassHeader.h"
namespace b
{
Interface::Interface(size_t m, const std::vector<double>& tt)
: _m(m), _tt(tt) {}
struct Interface::OriginalObj : public mainObj {
OriginalObj(size_t n, const std::vector<double>& t)
: _n(n),_t(t) {}
size_t _n;
std::vector<double> _t;
};
namespace a {
const std::vector<double> Child1::method1(size_t M, const std::vector<double>& vals)
{
return { static_cast<double>(M), vals[0] };
}
struct Child1::obj1 : public Interface::OriginalObj
{
// inherit constructor
using Interface::OriginalObj::OriginalObj;
Child1* owner;
double met(const std::vector<double>& vals) const override
{
std::vector<double> c = owner->method1(_n, vals);
return c[0];
}
};
Child1::Child1(size_t m, const std::vector<double>& tt)
:Interface(m, tt)
{
obj1 o1(m, tt); //new construction of o1
o1.owner = this; // does this initialize all the members as this?
}
auto Child1::make_obj(size_t M, const std::vector<double>& T) const
-> boost::shared_ptr<OriginalObj>
{
//return boost::make_shared<OriginalObj>(M, T);
return boost::shared_ptr<OriginalObj>{new Child1::obj1(M, T)};
}
} //namespace a
} // namespace b
I know I'm using it without calling it on the object (e.g. c1.method1(...)
), but I thought that since it was a class method it was somehow implied. Another issue I'm facing is that I cannot make the method static because it is virtual.
Can anyone please help me understand what I'm doing wrong and how I can solve the problem?
Thanks in advance!
I changed the code to reproduce the error. now I get the exact same error as in my actual code, in the same exact place. Hope this can help you find what I'm doing wrong.
Thanks again
答案1
得分: 1
obj1
没有默认构造函数。这是因为它继承自定义了非默认构造函数的 OriginalObj
,使得默认构造函数不存在(或已删除):
struct Interface::OriginalObj : public mainObj {
OriginalObj(size_t n, const std::vector<double>& t)
// ...
}
struct Child1::obj1 : public Interface::OriginalObj {
// ...
}
简单地定义 OriginalObj() = default;
可以解决这个问题,并将你带入下一个挑战,即 boost::make_shared<OriginalObj>(M, T);
试图构造一个抽象类的对象(met()
是纯虚函数)。你需要构造一个实际的 obj1
,它可以被强制转换为 OriginalObj
:
auto Child1::make_obj(size_t M, const std::vector<double>& T) const
-> boost::shared_ptr<OriginalObj>
{
return boost::shared_ptr<OriginalObj>{new Child1::obj1(M, T)};
}
完整演示: http://coliru.stacked-crooked.com/a/a24e42e600a92736
英文:
obj1
does not have a default constructor. This is because it inherits from OriginalObj
that defines a non-default constructor, rendering the defaulted default constructor non-existant (or deleted):
struct Interface::OriginalObj : public mainObj {
OriginalObj(size_t n, const std::vector<double>& t)
// ...
}
struct Child1::obj1 : public Interface::OriginalObj {
// ...
}
Simply defining OriginalObj() = default;
fixes that problem and set you up to the next challenge, being boost::make_shared<OriginalObj>(M, T);
tries to construct an object of an abstract class (met()
is pure virtual). You need to construct an actual obj1
which can be cast into an OriginalObj
:
auto Child1::make_obj(size_t M, const std::vector<double>& T) const
-> boost::shared_ptr<OriginalObj>
{
return boost::shared_ptr<OriginalObj>{new Child1::obj1(M, T)};
}
Full demo: http://coliru.stacked-crooked.com/a/a24e42e600a92736
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论