这个问题在某种程度上是 this one 的延续我已经发布了。
我想做的:我的意思是允许访问基类的私有(private)成员 A在派生类中 B , 具有以下限制:
std::map<> ,实际上——,不是一种方法;A没有模板化的方法,我可以作为后门替代方案重载——我不会添加这样的方法,因为它会反对第二个约束。作为一个可能的解决方案,有人指出我是 litb 的解决方案 ( post/blog ),但是,对于我来说,我一直无法理解这些帖子中所做的事情,因此,我无法得出解决问题的方法。
我正在尝试做的事情:以下代码来自 litb 的解决方案,提供了一种如何从类/结构访问私有(private)成员的方法,它恰好涵盖了我的限制提到。
所以,我正在尝试重新排列这段代码:
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// use
struct A {
A(int a):a(a) { }
private:
int a;
};
// tag used to access A::a
struct A_f {
typedef int A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*get(A_f()) << std::endl;
}
对于允许我执行以下操作的内容 -- 请注意,我将继承该类,因为 std::map<> 中的条目在派生类初始化后立即添加 B ,即 std::map<>不仅仅是类 A 的静态成员具有默认值,因此我需要从 B 的特定实例访问它:
// NOT MY CODE -- library <a.h>
class A {
private:
std::map<int, int> A_map;
};
// MY CODE -- module "b.h"
# include <a.h>
class B : private A {
public:
inline void uncover() {
for (auto it(A_map.begin()); it != A_map.end(); ++it) {
std::cout << it->first << " - " << it->second << std::endl;
}
}
};
我想要的答案:我真的喜欢让上面的代码工作——在适当的修改之后——但我会非常对第一个代码块(来自 litb 的解决方案)中所做的解释感到满意。
最佳答案
不幸的是,博文及其代码有点不清楚。这个概念很简单:显式模板实例化可以免费获得任何类的后台通行证,因为
分发此后台通行证的自然方式是作为指向成员的指针。如果您有一个指向给定类成员的指针,则可以在该类的任何对象中访问它,而不管访问资格如何。幸运的是,即使在 C++03 中,指向成员的指针也可以是编译时常量。
因此,我们需要一个在显式实例化时生成指向成员的指针的类。
显式实例化只是定义类的一种方式。仅生成一个类如何做某事?有两种选择:
friend 函数,它不是类的成员。这就是 litb 所做的。我会先介绍我的风格,然后讨论它的缺点,然后修改它以匹配 litb 的机制。最终结果仍然比博客中的代码简单。
该类采用三个模板参数:受限成员的类型、其实际名称以及对全局变量的引用以接收指向它的指针。该类调度一个要初始化的静态对象,其构造函数初始化全局对象。
template< typename type, type value, type & receiver >
class access_bypass {
static struct mover {
mover()
{ receiver = value; }
} m;
};
template< typename type, type value, type & receiver >
typename access_bypass< type, value, receiver >::mover
access_bypass< type, value, receiver >::m;
用法:
type_of_private_member target::* backstage_pass;
template class access_bypass <
type_of_private_member target::*,
& target::member_name,
backstage_pass
>;
target t;
t.* backstage_pass = blah;
不幸的是,在程序进入 main 之前,您不能依赖此结果可用于其他源文件中的全局对象构造函数,因为没有标准方法告诉编译器哪个顺序初始化文件。但是全局变量是按照它们声明的顺序初始化的,所以你可以把你的旁路放在顶部,只要静态对象构造函数不对其他文件进行函数调用就可以了。
通过添加标签结构和friend 函数,这从 litb 的代码中借用了一个元素,但这是一个很小的修改,我认为它仍然很清楚,并不比上面的差很多。
template< typename type, type value, typename tag >
class access_bypass {
friend type get( tag )
{ return value; }
};
用法:
struct backstage_pass {}; // now this is a dummy structure, not an object!
type_of_private_member target::* get( backstage_pass ); // declare fn to call
// Explicitly instantiating the class generates the fn declared above.
template class access_bypass <
type_of_private_member target::*,
& target::member_name,
backstage_pass
>;
target t;
t.* get( backstage_pass() ) = blah;
这个健壮的版本和 litb 的博客文章之间的主要区别在于我将所有参数收集到一个地方并使标签结构为空。它只是对相同机制的更清晰的接口(interface)。但是您必须声明 get 函数,博客代码会自动执行此操作。
关于c++ - 允许访问私有(private)成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15110526/
类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..
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我正在处理旧代码的一部分。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_
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我想从then子句中访问case语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案