我是 C++ 新手,有 Java 背景。我有一个类原型(prototype),它设置了两个私有(private)指针对象成员。
class DriveController : Controller {
public:
DriveController(
int8_t portTL_, int8_t portTR_, int8_t portBL_, int8_t portBR_,
double wheelSize_, double baseSize_);
private:
// Internal chassis controller
okapi::ChassisControllerIntegrated *chassisController;
okapi::AsyncMotionProfileController *chassisMotionProfiler;
现在,在我的此类的构造函数中,我使用我正在使用的 API 提供给我的工厂设计模式来初始化这两个变量。这是初始化这些类的唯一真实方法。
DriveController::DriveController(
int8_t portTL_, int8_t portTR_, int8_t portBL_, int8_t portBR_,
double wheelSize, double baseSize)
{
// Initialize port definitions
portTL = portTL_;
portTR = portTR_;
portBL = portBL_;
portBR = portBR_;
// Create chassis
auto chassis = okapi::ChassisControllerFactory::create(
{portTL, portBL}, // Left motors
{portTR, portBR}, // Right motors
okapi::AbstractMotor::gearset::red, // torque gearset
{wheelSize, baseSize} // wheel radius, base width
);
chassisController = &chassis;
auto profiler = okapi::AsyncControllerFactory::motionProfile(
1.0, 2.0, 10.0, *chassisController);
chassisMotionProfiler = &profiler;
}
我知道我在此处分配内存时做错了,因为当我尝试在稍后调用的函数中访问这些成员指针时,程序会出现“内存权限错误”错误。我一直在研究使用 unique_ptr 来存储对象,因为它们可以很好地管理生命周期,但是,由于创建对象的唯一方法是通过工厂初始化器,我一直无法找到构造 unique_ptr 的好方法。
初始化这些指针成员的正确方法是什么?
最佳答案
我首先要说这段代码看起来非常像 Java:对象是“做事者”( Controller 控制,配置文件配置文件)——为什么不在需要时控制和配置文件?这可能排除了对工厂的需求。
但忽略这一点,假设你确实需要这些点:
unique_ptr带有自定义删除器正如评论者所说,你们工厂的行为很奇怪。它们似乎返回类型为 okapi::ChassisControllerIntegrated 的值和 okapi::AsyncMotionProfileController分别(或可转换为这两者的类型)-一旦您获取了他们的地址。但这意味着工厂总是返回相同的类型,这首先违背了拥有工厂的目的(工厂可以通过指向基类的指针返回某个层次结构中任何类型的值)。如果是这种情况,那么,确实如@me' 所说 - 您创建的对象在离开构造函数的作用域时将被销毁。
如果你的工厂要返回指向这两个类的指针,代码会工作,但这将是一个坏主意,因为你需要在销毁时正确地释放两个指向的对象(甚至将它们送到工厂销毁)。
@BobBills 提出了一种避免这种情况的方法,即将创建的两个指针包装在 std::unique_ptr 中。的。这工作正常,但前提是您可以天真地解除分配它们。
我的建议是让工厂自己返回 std::unique_ptr s,具有他们需要您使用的特定删除功能。您真的根本不必担心删除 - 使用工厂的任何其他代码也不会。
构造函数代码为:
DriveController::DriveController(
int8_t portTL_, int8_t portTR_, int8_t portBL_, int8_t portBR_,
double wheelSize, double baseSize)
:
portTL{ portTL_}, portTR{ portTR_},
portBL{ portBL_}, portBR{ portBR_},
chassisController {
okapi::ChassisControllerFactory::create(
{portTL, portBL}, // Left motors
{portTR, portBR}, // Right motors
okapi::AbstractMotor::gearset::red, // torque gearset
{wheelSize, baseSize} // wheel radius, base width
)
},
chassisMotionProfiler {
okapi::AsyncControllerFactory::motionProfile(
1.0, 2.0, 10.0, chassisController)
}
{ }
(与@BobBills 的解决方案相同)- 好处是可以安全地假定析构函数是微不足道的:
DriveController::~DriveController() = default;
如果您的 DeviceController代码可以提前知道所有不同类型的底盘 Controller 和配置文件 Controller ,你确实可以让你的工厂返回一个值 - std::variant ,它可以包含几种固定类型中的任何一种的单个值,例如std::variant<int, double>可以容纳 int或 double ,但不是两者;它占用的存储空间比不同类型的最大存储空间多一点。这样你就可以完全避免指针,并且DeviceController将具有底盘和配置文件 Controller 的非指针成员。
另一种避免使用指针的方法是类型删除两个成员 Controller ,使用 std::any :如果这是工厂返回的内容,您将无法在基类上使用虚拟方法,但如果您的代码知道它应该得到什么 Controller 类型 - 它可以获得它,以类型安全的方式,来自 std::any .
关于C++ 适当的指针成员初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52789685/
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
如何将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%}定义的变量,我
我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于