我的library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
tags$style(HTML("
.box.box-solid.box-primary>.box-header {
}
.box.box-solid.box-primary{
background:#222d32
}
")),
fluidRow(
box(width = 6, title = "test", status = "primary", solidHeader
= TRUE,
"Box content"
)
)
)
)
server <- function(input, output) {}
shinyApp(ui, server)
库有这样的API:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
tags$style(HTML("
.box.box-solid.box-primary>.box-header {
color:#fff;
background:#222d32
}
.box.box-solid.box-primary{
border-bottom-color:#222d32;
border-left-color:#222d32;
border-right-color:#222d32;
border-top-color:#222d32;
background:#222d32
}
")),
fluidRow(
box(width = 6, title = "test", status = "primary", solidHeader =
TRUE,
"Box content"
)
)
)
)
server <- function(input, output) {}
shinyApp(ui, server)
为了简化它的用法,我用这样的方式包装它:
C
一切都很好,但是我必须包装这些不透明物体的数组:
extern "C" {
typedef struct Opaque Opaque;
Opaque *foo_new();
void foo_delete(Opaque *);
int foo_f(Opaque *, int);
}
所以我需要实现class Foo final {
public:
Foo() { self_ = foo_new(); }
~Foo() { foo_delete(self_); }
//code for copy/move constructor and operator=
int f(int a) { return foo_f(self_, a); }
private:
Opaque *self_;
};
:
extern "C" {
typedef struct OpaqueArray OpaqueArray;
OpaqueArray *calc_foo_array();
void foo_array_delete(OpaqueArray *);
Opaque *foo_array_elem(OpaqueArray *, size_t i);
}
但是我应该归结为class FooArray
?
我可以从class FooArray final {
public:
??? operator[](const size_t i) {
auto obj = foo_array_elem(self_, i);
???
}
private:
OpaqueArray *self_;
};
创建operator[]
,但Foo
是免费的数组部分,
怎么了。我可以创建与Opaque *
完全相同的Foo::~Foo()
,
但不要拨打FooRef
,但实际上我有几个Foo
,
我更喜欢不创建这么多代码重复。
可能我可以某种方式使用foo_delete
,因为C classes
并从reinterpret_cast
返回sizeof(Foo) = sizeof(Opaque *)
,但Foo &
实际上是operator[]
,
所以我需要在某处按住Foo &
以使其稳定。
对于这类问题,可能有一些标准解决方案吗?
答案 0 :(得分:4)
你可以修改你的Foo类,使它可以保存一个它不拥有的指针。
class Foo
{
public:
Foo()
{
self_ = foo_new();
m_owned = true;
}
Foo(Opaque *pOpaque)
{
self_ = foo_new();
m_owned = false;
}
~Foo()
{
if (m_owned) foo_delete(self_);
}
//code for copy/move constructor and operator=
int f(int a) { return foo_f(self_, a); }
private:
bool m_owned;
Opaque *self_;
};
class FooArray
{
public:
Foo operator[](const size_t i)
{
return Foo(foo_array_elem(self_, i));
}
private:
OpaqueArray *self_;
};
答案 1 :(得分:2)
我是按照你FooRef
提出的方式做的,但有点不同:
class FooRef {
public:
FooRef (Opaque *o) { self_ = o; }
int f(int a) { return foo_f(self_, a); }
protected:
Opaque *self_;
};
class Foo : public FooRef {
public:
Foo() { self_ = foo_new(); }
//code for copy/move constructor and operator=
~Foo () { foo_delete(self_); }
};
此解决方案避免了代码重复,并允许您安全地从数组返回Foo。顺便说一下,你有机制从FooRef
简单地创建Foo
。现在你可以做到:
class FooArray final {
public:
FooRef operator[](const size_t i) {
return FooRef(foo_array_elem(self_, i));
}
private:
OpaqueArray *self_;
};
我认为这应该以优雅的方式完成。