相关疑难解决方法(0)

pImpl成语是否真的在实践中使用?

我正在阅读Herb Sutter的"Exceptional C++"一书,在那本书中我学到了关于pImpl的习语.基本上,我们的想法是为a的private对象创建一个结构class并动态分配它们以减少编译时间(并且还以更好的方式隐藏私有实现).

例如:

class X
{
private:
  C c;
  D d;  
} ;
Run Code Online (Sandbox Code Playgroud)

可以改为:

class X
{
private:
  struct XImpl;
  XImpl* pImpl;       
};
Run Code Online (Sandbox Code Playgroud)

并且,在CPP中,定义:

struct X::XImpl
{
  C c;
  D d;
};
Run Code Online (Sandbox Code Playgroud)

这看起来很有趣,但我以前从未见过这种方法,既没有在我工作的公司,也没有在我看过源代码的开源项目中.所以,我想知道这种技术真的在实践中使用了吗?

我应该在任何地方使用它,还是谨慎使用?这种技术是否建议用于嵌入式系统(性能非常重要)?

c++ oop pimpl-idiom

157
推荐指数
7
解决办法
3万
查看次数

pimpl成语与桥梁设计模式

我刚刚注意到一个新术语pimpl成语,这个成语与Bridge设计模式有什么区别?我很困惑.

我也注意到pimpl成语总是用于交换功能,那是什么?有人可以举个例子吗?

c++ design-patterns

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

C++,私有函数真的需要在头文件中吗?

我一直认为头文件是一种描述类的"公共接口",在这种情况下,最好将私有字段和函数保存在cpp文件中.

我知道私有字段需要在头文件中,以便其他类可以告诉一个类的实例将消耗多少内存,但是当我要写一个私有帮助函数时,它就出现了,这个函数可以被创建静态,在这种情况下根本不需要它是"类的一部分",它可以很容易地成为类定义的.cpp文件中的常规函数​​.

然后我想到,通过接受指向类字段的指针/引用而不是期望在类中定义,所有私有函数都可能被重写为静态函数.

这将消除在头文件中声明任何私有函数的需要.

我喜欢遵循约定所以现在我想问一下,它是否被认为是C++中的既定约定,非静态私有函数应该在头文件中?静态函数或静态常量怎么样?

编辑:我将提供一些代码来解释我所得到的:

.h文件:

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

class SomeClass
{
private:
    int x;
public:
    void combineWithX(int y);
};

#endif
Run Code Online (Sandbox Code Playgroud)

.cpp文件

#include "SomeClass.h"

void someHelper(int* x)
{
    *x = (*x) + 1;
}

void SomeClass::combineWithX(int y)
{
    someHelper(&x);
    x += y;
}
Run Code Online (Sandbox Code Playgroud)

请注意,someHelper(int* x)在cpp文件中引用私有成员x,但不是直接引用,因此不需要出现在标题中.我想知道这种事情是否被认为是"坏风格"

c++ standards conventions

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

在C++中编写get/set方法变量的方法声明的样式?

你应该在.h文件中声明类的getters/setter,然后在.cpp中定义它们.或者在.h文件中同时执行它们.你喜欢哪种风格?为什么?我个人喜欢后者,其中所有这些都在.h中,并且只有与.cpp中的setter/getters相关的逻辑相关的方法.

c++ coding-style

6
推荐指数
2
解决办法
2942
查看次数

不同文件的类声明

我无法在这个网站上找到类似的问题,但是可以在两个不同的文件上声明一个类.

例如,文件和私有中的所有公共类组件以及不同文件中的其他组件.

publics.h

    class test {
     public:
        int geta();
        void seta(int); 
    };
Run Code Online (Sandbox Code Playgroud)

privates.h

    class test {
     private:
        int a;
    };
Run Code Online (Sandbox Code Playgroud)

上面的方法肯定是错的,但有没有这样的方法.

c++ class declaration

6
推荐指数
2
解决办法
1779
查看次数

现代C和C++:可以将一个定义的结构用于其他声明的结构吗?

假设我想制作一些应该支持加载图形Image的引擎,所以我有

 struct Image;
 Image* load_image_from_file(...);
Run Code Online (Sandbox Code Playgroud)

我不希望外部世界知道它到底Image是什么,它们只会指向它.

但是engine我想在内部使用特定类型,例如SDL_Surface在SDL中完全定义的类型.

我可以以某种方式重新映射此文件的图像,以便编译器在SDL_Surface*每次看到时都假定Image*(除了宏)吗?

即我想要的东西 typedef struct SDL_Surface Image;

所有尝试都喜欢

 using Image = SDL_Surface;
 typedef SDL_Surface Image;
 typedef struct SDL_Surface Image;
Run Code Online (Sandbox Code Playgroud)

产生编译时错误(http://codepad.org/1cFn18oh).

我知道我可以使用类似struct Image{SDL_Surface* surface};in engine.c/ engine.cpp但它会创建不必要的间接,我必须输入->surface.另一个肮脏的解决方案是使用显式转换,例如,((SDL_Surface*)image)但我更清楚重命名.

PS.我对C和C++的答案感兴趣.

c c++ class-design api-design

6
推荐指数
1
解决办法
182
查看次数

重新编译MFC扩展DLL会更改导出函数的入口点

我有一个导出C++类的MFC扩展DLL,我需要修改类方法的行为.这些更改不会影响类的方法签名.

我不想重新编译使用此库的先前发布版本的"lib"文件的模块.

如果更改修改了函数的入口点地址会发生什么?

例如,构造函数的地址已更改:

Export   Ordinal      Function    Hint                      Entry Point
[+  ]    3 (0x0003)   2 (0x0002)  ??0CLangManager@@QAE@XZ   0x00009CB0    (OLD DLL)
[+  ]    3 (0x0003)   2 (0x0002)  ??0CLangManager@@QAE@XZ   0x00009760    (NEW DLL)
Run Code Online (Sandbox Code Playgroud)

我应该重新编译使用该库的模块吗?

我测试了重新编译的库 - 使用新的入口点 - 使用已发布的可执行文件,一切正常.我不确定这种情况是否隐藏了一些副作用.

什么时候需要重新编译链接到DLL的可执行文件?

什么时候二进制兼容性被破坏了?

c++ dll mfc

5
推荐指数
1
解决办法
270
查看次数

指针,类别和范围

我似乎无法找到答案,但也许我正在寻找错误的术语.我没有在点击中找到我正在寻找的答案.

我有一堆菜单系统的派生类.

我有一个CControl派生类,它是CEditBox一个CLabel类和一个类的父类.CLabel只不过是将文本附加到SDL_Surface上,然后将其绑定到用于渲染的openGL的纹理. CEditBox将是一个用于显示文本或从用户收集文本的字段,如密码框.显然,CEditBox可以使用标签来处理框内的文本呈现. CControl源于CComponent.

我不能声明CLabel里面,CEditBox除非我包含CLabel在标题中,但我认为我继续得到链接器错误,尽管我的所有标题都包含在#ifndef #define class #endif语法中,但我也是一个菜鸟.相反,我有一个CComponent*指针声明,因为它们是从该类派生的.

精细.现在在CEditBox我的构造函数中:

#include "CLabel.h" //include in .CPP is fine I reckon.

CEditBox::CEditBox() {
    CLabel Field;      //Create CLabel
    InputType = ALL;   //Not important for my question related to allowed symbols
    Label = &Field;    //CComponent pointer to CLabel

}
Run Code Online (Sandbox Code Playgroud)

当这个构造函数返回时,CLabel不会超出范围,因此Feild会被销毁,现在我的指针指向一个未定义的内存块吗?什么是适当的方法来做到这一点?有更好的解决方案吗?

谢谢

链接器问题

我不知道问题已经存在,但有些人认为这是一个更重要的问题.那么现在是实际的代码,你们可以告诉我你是否认为它做错了.基类CMenuObject

#ifndef _CMENUOBJECT_H_
#define _CMENUOBJECT_H_
class CMenuObject { …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance pointers scope class

5
推荐指数
1
解决办法
226
查看次数

在delphi中的父类和子类之间进行转换

我正在编写一些针对两个非常相似的硬件版本的软件,直到我使用API​​来初始化硬件,我才知道我会找回哪种类型.

因为硬件非常相似,我计划有一个父类(TParent),它有一些抽象方法(对于硬件不同的地方),然后是两个子类(TChildA,TChildB),它们以硬件相关的方式实现这些方法.

所以我首先实例化一个TParent的对象检查它是什么样的,然后把它投射到正确的孩子.

但是,当我这样做并调用在子类中完全实现的抽象方法之一时,我得到一个EAbstractError.

例如:

myHardware:=TParent.Create();

if myHardware.TypeA then
   myHardware:=TChildA(myHardware)
else
   myHardware:=TChildB(myHardware);

myHardware.SomeMehtod();
Run Code Online (Sandbox Code Playgroud)

我假设我不能将父类强制转换为子类,并且还有一种更好的方法可以做到这一点.有什么指针吗?

delphi oop freepascal

4
推荐指数
1
解决办法
3580
查看次数

稍后创建QScopedPointer的实例

例如,这是我的代码

QScopedPointer<QTimer> timer2(new QTimer);
Run Code Online (Sandbox Code Playgroud)

但我想定义

QScopedPointer<QTimer> timer2; 
Run Code Online (Sandbox Code Playgroud)

在mainwindow.h中创建一个实例

timer2(new QTimer);
Run Code Online (Sandbox Code Playgroud)

在mainwindow.cpp中

怎么样?

qt pointers qscopedpointer

4
推荐指数
1
解决办法
2054
查看次数