我正在尝试实现访问者模式的示例,但是我对类的声明的循环依赖有困难.在进行上课访客的申报的时候,俄罗斯和英格兰的班级不知道访问者有方法访问,但是在接受方法接受的访问者的申报的时候,需要使用英国和俄罗斯的班级,但是他们需要知道谁访问者是,因为他们在代码中使用此类型.我尝试了许多订购代码的变体,但我完全失败了.请帮助我理解C++需要什么才能得到这个.谢谢.
#include <cstdio>
#include <vector>
using namespace std;
class Visitor;
class Land {
public:
virtual void accept(const Visitor *v);
};
class England : public Land {
public:
void accept(const Visitor *v) {
v->visit(this);
}
};
class Russia : public Land {
public:
void accept(const Visitor *v) {
v->visit(this);
}
};
class Visitor {
public:
void visit(const England *e) const {
printf("Hey, it's England!\n");
}
void visit(const Russia *r) const {
printf("Hey, it's Russia!\n");
}
};
class Trip {
private:
vector<Land> … 您好,我已经阅读过有关此主题的类似问题,但我无法解决我的问题。我想我必须做一个前瞻性声明,所以我尝试了以下操作。
我有三个类 A、B 和 InterfaceA
定义接口A
#ifndef INTERFACE_A_H
#define INTERFACE_A_H
#include "B.h"
namespace Example
{
class B; // Forward declaration?
class InterfaceA
{
Example::B test;
};
}
#endif
Run Code Online (Sandbox Code Playgroud)
定义A类
#ifndef A_H
#define A_H
#include "InterfaceA.h"
namespace Example
{
class A : public Example::InterfaceA
{
};
}
#endif
Run Code Online (Sandbox Code Playgroud)
定义B类
#ifndef B_H
#define B_H
#include "A.h"
namespace Example
{
class A; // Forward declaration?
class B
{
Example::A test;
};
}
#endif
Run Code Online (Sandbox Code Playgroud)
主要的
#include "A.h"
#include "B.h"
int main()
{
Example::A a; …Run Code Online (Sandbox Code Playgroud) 我是C++的新手,但我确实有一些Java经验.编码时,我偶然发现了一个让我感到困惑的错误.这是我的代码(简化,但错误是相同的):
啊:
#pragma once
#include "B.h"
class A
{
public:
A();
void foo();
void sayHello();
B b;
};
Run Code Online (Sandbox Code Playgroud)
A.cpp:
#include "A.h"
#include <iostream>
A::A() {}
void A::foo() {
b.bar(this);
}
void A::sayHello() {
std::cout << "Hello" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
BH:
#pragma once
#include "A.h"
class B
{
public:
B();
void bar(A *a);
};
Run Code Online (Sandbox Code Playgroud)
B.cpp:
#include "B.h"
B::B(){}
void B::bar(A *a) {
a->sayHello();
}
Run Code Online (Sandbox Code Playgroud)
我想了一个指针传递一个对象到酒吧在功能上乙,这样我就可以修改并访问一个在的领域吧.奇怪的是,当我通过另一个类的A实例调用foo时,我得到了这些错误:
1>------ Build …Run Code Online (Sandbox Code Playgroud) 在下面的例子中,struct Yfoward声明的前向声明是不够的.如果你注释掉X :: b,它编译得很好,因为Y有一个完整的结构声明可以使用,但X只有前向声明.
#include <functional>
#include <iostream>
struct Y;
struct X
{
std::function<bool(Y&)> b{[] (auto& y_) { return y_.a; }};
bool a{false};
};
struct Y
{
std::function<bool(X&)> b{[] (auto& x_) { return x_.a; }};
bool a{true};
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以下是我可以提出的解决方案:
#include <functional>
#include <iostream>
struct Y;
struct X
{
X();
std::function<bool(Y&)> b;
bool a{false};
};
struct Y
{
Y();
std::function<bool(X&)> b{[] (auto& x_) { return x_.a; }};
bool …Run Code Online (Sandbox Code Playgroud) 我最初的怀疑是我的代码中存在循环依赖,并且通过Resolve头包含循环依赖.但这并没有解决我的编译错误.这是包含3个类的代码 - A,G和N.
//A.h
#ifndef A_H_
#define A_H_
class com::xxxx::test::G;
namespace com { namespace xxxx { namespace test {
class A {
public:
A();
~A();
void method1(void);
private:
G* g;
};
} } }
#endif /* A_H_ */
//A.cpp
#include "A.h"
#include "G.h"
namespace com { namespace xxxx { namespace test {
A::A() {
g = new com::xxxx::test::G();
}
A::~A() {
delete g;
}
void A::method1() {
g->method2(*this);
}
} } }
//G.h
#ifndef G_H_
#define G_H_
class …Run Code Online (Sandbox Code Playgroud) placeable.h
#include "selectable.h"
class placeable : selectable
{
..
};
Run Code Online (Sandbox Code Playgroud)
selectable.h
#include "game.h"
class selectable
{
..
};
Run Code Online (Sandbox Code Playgroud)
game.h
#include "placeable.h"
class game
{
...
class placeable* holding;
...
};
Run Code Online (Sandbox Code Playgroud)
基本上placeable.h包括selectable.h,其中包括game.h,其中包括placeable.h.
我能想到的唯一解决方案是将placeable*放在一个新的头文件中,使其成为静态/全局,然后在game.h和selectable.h中包含这个新头文件.
对不起,我在上面的代码中包含了标题保护.我认为很明显.在这种情况下,由于继承,标题保护没有帮助,同样的事情与前向声明一致.
如果我有多个文件#include彼此,以及所有#include <iostream>,这被认为是坏的,如果是这样,我将如何避免它?
我有这个文件logger.hpp:
#ifndef _LOGGER_HPP_
#define _LOGGER_HPP_
#include "event.hpp"
// Class definitions
class Logger {
public:
/*!
* Constructor
*/
Logger();
/*!
* Destructor
*/
~Logger();
/*!
* My operator
*/
Logger& operator<<(const Event& e);
private:
...
};
#endif
Run Code Online (Sandbox Code Playgroud)
而这个文件是event.hpp
#ifndef _EVENT_HPP_
#define _EVENT_HPP_
#include <string>
#include "logger.hpp"
// Class definitions
class Event {
public:
/*!
* Constructor
*/
Event();
/*!
* Destructor
*/
~Event();
/* Friendship */
friend Logger& Logger::operator<<(const Event& e);
};
#endif
Run Code Online (Sandbox Code Playgroud)
好.在logger.hpp中我包含event.hpp,在event.hpp中我包含logger.hpp.
我需要包含event.hpp,因为在logger.hpp中我需要定义运算符.
我需要包含logger.hpp,因为在event.hpp中,要在类Event中定义友谊.
当然,这是一个循环递归.
我试过这个: …
我正在尝试在 C++ 中进行简单的回调,但是我在按照我的意愿进行操作时遇到了问题。
基本上我想要这样的东西:
class A{
void A::AddCallback(void (*callBackFunction)(string)){
/*Code goes here*/
}
}
Run Code Online (Sandbox Code Playgroud)
和B级
#include "A.h"
class B{
B::B(){
A childObject;
childObject(MyCallBackFunction);
}
B::MyCallBackFunction(string arg){
/*Code goes here*/
}
}
Run Code Online (Sandbox Code Playgroud)
我知道通常你会想AddCallback用类似的东西定义标题,B::callBackFunction但我确实需要导入A,B所以让两个类相互导入会很尴尬。我知道我以前见过这个,但我无法正确理解语法
我在两个不同的文件中定义了以下两个类:
#include "B.h"
class A {
public:
A() {}
~A() {}
f() {
auto b = new B(this);
}
};
Run Code Online (Sandbox Code Playgroud)
在另一个文件中:
#include "A.h"
class B {
public:
B(A* a) {}
~B() {}
}
Run Code Online (Sandbox Code Playgroud)
但我不明白我得到的编译错误:
B.h: error: ‘A’ has not been declared
A.cpp: error: no matching function for call to ‘B(A&)‘
*this);
note: candidate is:
note: B(int*)
note: no known conversion for argument 1 from ‘A’ to ‘int*’
Run Code Online (Sandbox Code Playgroud)
为什么我的A类已经转换为int?
c++ ×10
c++11 ×2
header-files ×2
this ×2
header ×1
include ×1
inheritance ×1
member ×1
pointers ×1