抱歉标题又长又乱。
我有一个这样的类头文件
#pragma once
#include <thread>
#include <boost/asio.hpp>
#include <another3rdpartylib/doodads.h>
class A {
public:
A();
Method1();
Method2();
private:
std::thread thread;
boost::asio::socket socket;
another3dpartylib::doodad gizmo;
}
现在类的用户不会也不应该关心私有(private)部分。
我怎样才能允许用户在不拖动的情况下包含类 <thread> , <boost/asio.hpp>和 <another3rdpartylib/doodads.h> ?
从技术上讲,用户唯一应该关心的是 sizeof(A) .我错了吗?
最佳答案
C++中分离类的接口(interface)和实现的常用方法是使用Pointer To Implementation (PIMPL) Idiom .
PIMPL 习语通过存储对负责执行操作的类的引用/指针来封装类的实现,只为用户提供一个类,即接口(interface),它仅充当实现类的包装器.
例如:考虑一个为浮点运算实现极快堆栈的库。容器的接口(interface)非常简单:
class fast_stack
{
public:
void push( float );
float pop();
};
但是由于这个库实现了一个极快的堆栈,它的实现是基于极其复杂的库、内联汇编、brainfuck 互操作性等。
该库的用户只需要一个堆栈,而不是一堆可怕的代码、库和依赖项。 我们如何才能隐藏所有的尖叫声,只为他提供一个简单干净的界面?这就是 PIMPL 发挥作用的地方:
//stack_inferno.hpp
#include <thread>
#include <Boost/ASIO>
... More monters here
class fast_stack_infernal_implementation
{
std::thread* _mptr_thread_lcl;
float******* _suicide_cache_memory_pool;
... etc etc
void push( float elem )
{
//Please don't see this code, it could hurt your eyes
}
float pop()
{
// Same as above
}
};
//fast_stack.hpp (Revisited)
class fast_stack_infernal_implementation; //Note the forward declaration.
class fast_stack
{
public:
void push( float );
float pop();
private:
std::unique_ptr<fast_stack_infernal_implementation> implm;
};
//fast_stack.cpp
#include "stack_inferno.hpp" //Tah daah!
fast_stack::fast_stack() : impl( new fast_stack_infernal_implementation() )
{
}
void fast_stack::push( float elem )
{
implm->push( elem );
}
float fast_stack::push()
{
return implm->pop();
}
如您所见,PIMPL 习语有很多优点:
关于c++ - 允许用户包含类而不包含用于私有(private)的 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20804621/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。