我有一个B类,我想把成员称为A类.所以:
1.
//A.h
class B;
class A
{
private:
B* m_p;
};
//a.cpp
#include "B.h"
Run Code Online (Sandbox Code Playgroud)
2.
// A.h
#include "B.h"
class A
{
private:
B * impl_;
};
Run Code Online (Sandbox Code Playgroud)
当一个没有太多依赖性的小项目涉及时,这两种方式是否更好?
考虑以下两种情况(编辑只是为了完成整个问题并使其更清晰)
案例1 :(如下面正确提到的那样编译)
//B.h
#ifndef B_H
#define B_H
#include "B.h"
class A;
class B {
A obj;
public:
void printA_thruB();
};
#endif
//B.cpp
#include "B.h"
#include <iostream>
void B::printA_thruB(){
obj.printA();
}
//A.h;
#ifndef A_H
#define A_H
#include "A.h"
class A {
int a;
public:
A();
void printA();
};
#endif
//A.cpp
#include "A.h"
#include <iostream>
A::A(){
a=10;
}
void A::printA()
{
std::cout<<"A:"<<a<<std::endl;
}
//main.cpp
#include "B.h"
#include<iostream>
using namespace std;
int main()
{
B obj;
obj.printA_thruB();
}
Run Code Online (Sandbox Code Playgroud)
案例2 :(唯一的修改......没有编译错误)
//B.h
#include …Run Code Online (Sandbox Code Playgroud) 并不是说谷歌风格指南是神圣的圣经,但作为一个新手程序员,它似乎是一个很好的参考.
Google样式指南列出了前向声明的以下缺点
前向声明可以隐藏依赖项,允许用户代码在标题更改时跳过必要的重新编译.
随后对库的更改可能会破坏前向声明.函数和模板的前向声明可以防止标题所有者对其API进行其他兼容的更改,例如扩展参数类型,添加具有默认值的模板参数或迁移到新的命名空间.
从名称空间std ::转发声明符号会产生未定义的行为.
可能很难确定是否需要前向声明或完整#include.用前向声明替换#include可以默默地改变代码的含义:
码:
// b.h:
struct B {};
struct D : B {};
// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) { f(x); } // calls f(B*)
Run Code Online (Sandbox Code Playgroud)
如果#include被B和D的forward decls替换,test()将调用f(void*).
从标题中声明多个符号的前向可能比简单地#include the header更加冗长.
构造代码以启用前向声明(例如,使用指针成员而不是对象成员)可以使代码更慢,更复杂.
然而,对SO的一些搜索似乎表明,前向声明通常是更好的解决方案.
因此,鉴于这些看似非平凡的缺点,有人可以解释这种差异吗?
什么时候忽略部分或全部这些缺点是安全的?
我很清楚何时能够/不能使用前瞻性声明,但我仍然不确定一件事.
假设我知道我迟早要包括一个标题来取消引用A类的对象.我不清楚是否更有效地做类似的事情.
class A;
class B
{
A* a;
void DoSomethingWithA();
};
Run Code Online (Sandbox Code Playgroud)
然后在cpp有类似的东西..
#include "A.hpp"
void B::DoSomethingWithA()
{
a->FunctionOfA();
}
Run Code Online (Sandbox Code Playgroud)
或者我也可以首先在B的头文件中包含A的标题?如果前者效率更高,那么如果有人清楚地解释了为什么我怀疑它与编译过程有关,我可以随时了解更多信息,我会很感激.
我必须重构一个旧代码.它的一个问题是它超过了无用的"包括".在同一个项目中,我看到了以下语法:
#include <AnyClass> //A system header
#include "AnotherAnyClass" //A application header
class AnotherClass;
class Class : public OneMoreClass
{
public:
explicit Class();
~Class();
private:
AnotherClass *m_anotherClass;
}
Run Code Online (Sandbox Code Playgroud)
我想弄明白:
我正在阅读有关使用Qt5(作者Max Schlee)的书,我注意到一些例子已经在头文件中声明了现有的Qt类,例如:
class QProgressBar;
Run Code Online (Sandbox Code Playgroud)
所以,我的问题 - 为什么我们不在头文件中包含头文件QProgressBar而不class QProgressBar;在我们的头文件中声明?
我看到了这个构造函数:
MyClass(class MyOtherClass* = 0) {}
Run Code Online (Sandbox Code Playgroud)
什么是class关键字是什么意思?构造函数是否采用MyOtherClass指针并将参数默认为空指针?
我有功能做一些工作.
啊
void doSomething(int n);
Run Code Online (Sandbox Code Playgroud)
A.cpp
#include "A.h"
void doSomething(int n) {
/* something */
}
Run Code Online (Sandbox Code Playgroud)
如果我想在另一个源文件中使用此函数,最佳选择是什么:
1)包括啊
B.cpp
#include "A.h"
void anotherTask() {
// ...
doSomething(5);
// ...
}
Run Code Online (Sandbox Code Playgroud)
2)或使用前向声明(函数原型):
B.cpp
void doSomething(int);
void anotherTask() {
// ...
doSomething(5);
// ...
}
Run Code Online (Sandbox Code Playgroud)
关于类的使用前向声明有很多提示.那么,功能前向声明的最佳实践是什么?
UPD
好的,这是一个太简单的例子.
如果标题啊有一些垃圾怎么办(相对于B.cpp,它对驱动程序级别一无所知):
啊
#include "specific_driver_header.h" /* some lowlevel stuff that B.cpp couldn't know */
#define SPECIFIC_DRIVER_DEFINES 0xF0 /* useless define for B.cpp that uses global namespace */
void doSomething(int n); /* only significant function for …Run Code Online (Sandbox Code Playgroud) 我发现这个问题什么时候使用前向声明?这是有用的,但它是描述性的而不是规定性的.
我的场景通常是我使用指向另一个类的指针作为类成员或函数参数,所以我在标题中需要的只是一个前向声明(另外,如果我切换到使用boost shared_ptr,它们将是与使用前向声明兼容?).目前我只是包括标题,但现在我想知道我是否应该使用前向声明.
所以我的问题是,如果我可以使用前瞻性声明,我应该吗?我希望这个问题不是主观的,但如果没有最佳实践答案,那么使用前瞻性声明的利弊是什么?
UPDATE
只是为了扩展shared_ptr问题(我现在没有使用它们,而是考虑切换).如果我要使用它们,我想我会在类中使用typedef的shared_ptr类型.例如:
class Customer
{
public:
typedef std::tr1::shared_ptr<Customer> SharedPointer;
Customer() {}
virtual ~Customer() {}
virtual std::string GetName() const;
};
Run Code Online (Sandbox Code Playgroud)
似乎这可能会使事情变得更加混乱.这会对前向声明产生问题,如果是这样,有一个简单的解决方法吗?
可能重复:
应将"include"放在C++中
显然,关于是否将#include指令放入C++头文件(或者作为替代,#include仅放入cpp文件),有两种"思想流派" .有人说没关系,有人说这只会导致问题.有人知道这个讨论是否已经得出结论什么是首选的?
我试图通过const引用将一个对象(类库存)传递给另一个类的函数(称为Algorithms).
//Algorithms.h
#pragma once
class Algorithms
{
public:
Algorithms(void);
~Algorithms(void);
int Algorithms::doAnalysis(const Stock&);
};
Run Code Online (Sandbox Code Playgroud)
doAnalysis的实现是
#include "StdAfx.h"
#include "Algorithms.h"
#include "Stock.h"
#include <vector>
using namespace std;
Algorithms::Algorithms(void)
{
}
Algorithms::~Algorithms(void)
{
}
int Algorithms::doAnalysis(const Stock &S)
{
//Do Something
return 0;
}
Run Code Online (Sandbox Code Playgroud)
类Stock有以下构造函数
public:
Stock(std::string market, std::string symbol);
Stock(std::string market, std::string symbol, std::string start_date, std::string end_date);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Error: declaration is imcompatible with "int Algorithms::doAnalysis(const<error-type> &)" declared at line 8 of Algorithms.h
Run Code Online (Sandbox Code Playgroud)
我知道没有找到班级股票.我应该如何在Algorithms.h中声明doAnalysis方法以便找到它?股票不是派生类.
谢谢你的帮助.我是C++的新手.