相关疑难解决方法(0)

是否需要std :: unique_ptr <T>才能知道T的完整定义?

我在头文件中有一些代码如下:

#include <memory>

class Thing;

class MyClass
{
    std::unique_ptr< Thing > my_thing;
};
Run Code Online (Sandbox Code Playgroud)

如果我有一个CPP这个头不包含的Thing类型定义,那么这并不在VS2010 SP1的编译:

1> C:\ Program Files(x86)\ Microsoft Visual Studio 10.0\VC\include\memory(2067):错误C2027:使用未定义类型'Thing'

替换std::unique_ptrstd::shared_ptr和编译.

所以,我猜这是当前VS2010 std::unique_ptr的实现,需要完整的定义,而且完全依赖于实现.

或者是吗?它的标准要求中是否有某些东西使得std::unique_ptr实施只能使用前向声明?感觉很奇怪,因为它应该只有一个指针Thing,不应该吗?

c++ stl visual-studio-2010 unique-ptr c++11

236
推荐指数
5
解决办法
4万
查看次数

为什么我的包含防护不能阻止递归包含和多个符号定义?

关于包括警卫的两个常见问题:

  1. 第一个问题:

    为什么不包括保护我的头文件不受相互的,递归包含的警卫?我不断收到有关不存在的符号的错误,这些符号显然存在,甚至每次我写下类似的东西时都会出现更奇怪的语法错误:

    "啊"

    #ifndef A_H
    #define A_H
    
    #include "b.h"
    
    ...
    
    #endif // A_H
    
    Run Code Online (Sandbox Code Playgroud)

    "BH"

    #ifndef B_H
    #define B_H
    
    #include "a.h"
    
    ...
    
    #endif // B_H
    
    Run Code Online (Sandbox Code Playgroud)

    "的main.cpp"

    #include "a.h"
    int main()
    {
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    为什么我会收到编译"main.cpp"的错误?我需要做些什么来解决我的问题?


  1. 第二个问题:

    为什么不包括防止多个定义的警卫?例如,当我的项目包含两个包含相同标题的文件时,链接器有时会抱怨多次定义某个符号.例如:

    "header.h"

    #ifndef HEADER_H
    #define HEADER_H
    
    int f()
    {
        return 0;
    }
    
    #endif // HEADER_H
    
    Run Code Online (Sandbox Code Playgroud)

    "source1.cpp"

    #include "header.h"
    ...
    
    Run Code Online (Sandbox Code Playgroud)

    "source2.cpp"

    #include "header.h"
    ...
    
    Run Code Online (Sandbox Code Playgroud)

    为什么会这样?我需要做些什么来解决我的问题?

c++ c++-faq include-guards header-files

70
推荐指数
1
解决办法
2万
查看次数

C++标题顺序

标头/ cpp文件中应标头的顺序是什么?显然,后续标题所需的那些应该更早,特定于类的标题应该在cpp范围内而不是标题范围,但是是否有一个集合顺序约定/最佳实践?

c++ header code-organization include

34
推荐指数
4
解决办法
2万
查看次数

前瞻声明与包含

考虑以下两种情况(编辑只是为了完成整个问题并使其更清晰)

案例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)

c++ class forward-declaration

19
推荐指数
2
解决办法
3万
查看次数

C++ - 在初始化类成员之前运行一个函数

我有2个资源管理类DeviceContext,OpenGLContext都是class DisplayOpenGL.资源生命周期与之相关DisplayOpenGL.初始化看起来像这样(伪代码):

DeviceContext m_device = DeviceContext(hwnd);
m_device.SetPixelFormat();
OpenGLContext m_opengl = OpenGLContext(m_device);
Run Code Online (Sandbox Code Playgroud)

问题是调用SetPixelFormat(),因为我无法在DisplayOpenGLc'tor 的初始化列表中执行此操作:

class DisplayOpenGL {
public:
    DisplayOpenGL(HWND hwnd)
    : m_device(hwnd),
      // <- Must call m_device.SetPixelFormat here ->
      m_opengl(m_device) { };
private:
    DeviceContext m_device;
    OpenGLContext m_opengl;
};
Run Code Online (Sandbox Code Playgroud)

我能看到的解决方案:

  • 插入m_dummy(m_device.SetPixelFormat())- 无法工作,因为SetPixelFormat()没有retval.(如果它有一个retval,你应该这样做吗?)
  • unique_ptr<OpenGLContext> m_opengl;而不是OpenGLContext m_opengl;.
    然后初始化为m_opengl(),在c'tor体中调用SetPixelFormat()并使用m_opengl.reset(new OpenGLContext);
  • SetPixelFormat()来自DeviceContextc'tor的 电话

哪种解决方案更可取?为什么?我错过了什么?

我在Windows上使用Visual Studio 2010 Express,如果重要的话.

编辑:我最感兴趣的是在决定使用其中一种方法时所涉及的权衡.

  • m_dummy() 不工作,即使它会显得不优雅
  • unique_ptr<X>对我来说很有意思 …

c++ constructor initialization smart-pointers initialization-list

19
推荐指数
2
解决办法
5152
查看次数

关于C++包括另一个类

我有两个文件:

File1.cpp
File2.cpp
Run Code Online (Sandbox Code Playgroud)

File1是我的主类,它有main方法,File2.cpp有一个类调用ClassTwo,我想在File1.cpp中创建一个ClassTwo对象

我一起编译它们

g++ -o myfile File1.cpp File2.cpp
Run Code Online (Sandbox Code Playgroud)

但是当我尝试创造时

//创建第二类对象

ClassTwo ctwo;
Run Code Online (Sandbox Code Playgroud)

它不起作用.

错误是

ClassTwo未在此范围内声明.

这是我的main.cpp

#include <iostream>
#include <string>
using namespace std;

int main()
{
//here compile error - undeclare ClassTwo in scope.
ClassTwo ctwo;

//some codes
}
Run Code Online (Sandbox Code Playgroud)

这是我的File2.cpp

#include <iostream>
#include <string>

using namespace std;

class ClassTwo
{
private:
string myType;
public:
void setType(string);
string getType();
};


void ClassTwo::setType(string sType)
{
myType = sType;
}

void ClassTwo::getType(float fVal)
{
return myType;
}
Run Code Online (Sandbox Code Playgroud)

得到了将我的File2.cpp拆分成另一个.h文件的响应但是如果我声明一个类,我如何将它拆分成另一个.h文件,因为我需要维护变量(私有)和函数的公共和私有(公共) )如何在main方法中将ClassTwo ctwo转换为File1.cpp

c++

18
推荐指数
2
解决办法
10万
查看次数

C++,类作为方法的参数,而不是模板

所以,我遇到了一个我不太了解的有趣方法签名,它遵循以下方式:

void Initialize(std::vector< std::string > & param1, class SomeClassName * p);
Run Code Online (Sandbox Code Playgroud)

我不明白的是"class"关键字被用作参数,为什么会出现?是否有必要指明或纯粹是肤浅的?

c++ class

15
推荐指数
1
解决办法
1967
查看次数

循环C++标题包含

在一个项目中,我有两个类:

// mainw.h

#include "IFr.h"
...
class mainw
{
public:
static IFr ifr;
static CSize=100;
...
};
Run Code Online (Sandbox Code Playgroud)

// IFr.h

#include "mainw.h"
...
class IFr
{
public float[mainw::CSize];
};
Run Code Online (Sandbox Code Playgroud)

但我无法编译此代码,在该static IFr ifr;行收到错误.是否禁止这种交叉包含?

c++ static circular-dependency include

14
推荐指数
1
解决办法
8248
查看次数

头文件包含/转发声明

在我的C++项目中何时必须使用#include "myclass.h"头文件的includes()?我什么时候必须使用class(class CMyClass;)的前向声明?

c++ header-files forward-declaration

13
推荐指数
4
解决办法
2万
查看次数

为什么包含头文件这么邪恶?

我已经看到很多关于何时使用前向声明而不是包含头文件的解释,但是很少有人解释为什么这样做很重要.我见过的一些原因包括:

  • 编译速度
  • 降低头文件管理的复杂性
  • 删除循环依赖项

来自.net背景我发现标题管理令人沮丧.我有这种感觉我需要掌握前向声明,但到目前为止我一直在报废.

为什么编译器不能为我工作并使用一种机制(包括)找出我的依赖关系?

前向声明如何加速编译,因为在某些时候引用的对象需要编译?

我可以购买降低复杂性的论据,但这样做的实际例子是什么呢?

c++ header-files forward-declaration

12
推荐指数
1
解决办法
2499
查看次数