有没有办法强制this关键字作为ref参数?我想传入一个修改对象上的多个属性的访问者,但这只是想要像值参数一样.
对象代码:
public void Accept(Visitor<MyObject> visitor)
{
visitor.Visit(this);
}
Run Code Online (Sandbox Code Playgroud)
访客代码:
public void Visit(ref Visitor<MyObject> receiver)
{
receiver.Property = new PropertyValue();
receiver.Property2 = new PropertyValue();
}
Run Code Online (Sandbox Code Playgroud) 注意:为澄清起见,问题不是restrict一般地使用关键字,而是具体地将关键字应用于此处所述的成员函数。
gcc允许您在成员函数上使用__restrict__(相当于C99的GNU ++ restrict)限定符,从而有效地this在函数范围内创建了限定限定的指针。牛肉在哪里?
大多数成员函数上的其他成员的工作,通过访问它们this,这是一个T* const(并且通常非混淆)。为了this可能被别名,在成员函数内将需要使用第二个指向类型的指针,并且它必须来自某个地方。
这是非成员函数经常发生的情况,例如所有二进制运算符或采用至少两个相同或非平凡类型的指针或引用的其他自由函数。但是,这些函数没有this,因此它们不相关。
赋值运算符,拷贝构造,和一元比较运算符,其中的成员函数的实例this 可以 在原则上被混叠(因为另一个目的通过引用传递)。因此,给它们分配一个限制限定符才是真正有意义的-编译器应该已经清楚所有其他函数仍然具有限制属性(因为永远不会有第二个指向T的指针)。
现在,例如,如果你用restrict的operator=你应该必然不检查所有自赋值,因为你说this是不是该函数的范围内的别名(以及如果这是真的,没有自我的分配也可能会发生)。
显然,这是您可能无法事先知道的,也是没有意义的。
那么,在一种情况下,人们实际上想给成员函数一个限制限定符,并且有意义吗?
由于std::function可以保存成员函数,因此它必须在某处存储指向对象实例的指针.
如何this从std::function包含成员函数的指针中获取指针?
正如预期的那样,以下代码不会编译
#include <iostream>
class A
{
public:
A() = default;
~A() = default;
A(const A&) = delete;
A(A&&) = delete;
A& operator=(const A&) = delete;
A& operator=(A&&) = delete;
A& operator<<(const int i)
{
std::cout << "operator<< called" << std::endl;
return *this;
}
};
void foo(A&& a)
{
std::cout << "foo called" << std::endl;
}
int main()
{
A a; a << 14;
foo(std::move(a)); // works fine
foo(A() << 14); // does not compile
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将A类改为
class A …Run Code Online (Sandbox Code Playgroud) 我正在阅读Bjarne的论文:C++的多重继承.
在第370页的第3节中,Bjarne说:"编译器将成员函数的调用转换为带有"额外"参数的"普通"函数调用;"额外"参数是指向成员函数的对象的指针叫做."
我对这个额外的论点感到困惑.请看以下两个例子:
示例1 :(第372页)
class A {
int a;
virtual void f(int);
virtual void g(int);
virtual void h(int);
};
class B : A {int b; void g(int); };
class C : B {int c; void h(int); };
Run Code Online (Sandbox Code Playgroud)
类c对象C看起来像:
C:
----------- vtbl:
+0: vptr --------------> -----------
+4: a +0: A::f
+8: b +4: B::g
+12: c +8: C::h
----------- -----------
Run Code Online (Sandbox Code Playgroud)
对虚函数的调用由编译器转换为间接调用.例如,
C* pc;
pc->g(2)
Run Code Online (Sandbox Code Playgroud)
变成这样的东西:
(*(pc->vptr[1]))(pc, 2)
Run Code Online (Sandbox Code Playgroud)
Bjarne的论文告诉我上述结论.传球this点是C*.
在下面的例子中,Bjarne讲了另一个让我困惑的故事!
示例2 :(第373页)
鉴于两个班级
class A {...};
class …Run Code Online (Sandbox Code Playgroud) c++ pointers virtual-functions multiple-inheritance this-pointer
刚才我震惊地发现以下是合法的(C#等价物绝对不是):
Class Assigner
''// Ignore this for now.
Public Field As Integer
''// This part is not so weird... take another instance ByRef,
''// assign it to a different instance -- stupid but whatever. '
Sub Assign(ByRef x As Assigner, ByVal y As Assigner)
x = y
End Sub
''// But... what's this?!?
Sub AssignNew()
''// Passing "Me" ByRef???
Assign(Me, New Assigner)
End Sub
''// This is just for testing.
Function GetField() As Integer
Return Me.Field
End Function
End Class …Run Code Online (Sandbox Code Playgroud) 我有主类,我喜欢将其指针引用传递给我创建的对象,但它给了我错误:
错误1错误C2664:'GameController :: GameController(GameLayer*&)':无法将参数1从'GameLayer*const'转换为'GameLayer*&'
我在GameLayer中有什么(主要对象)
m_pGameController = new GameController(this);
Run Code Online (Sandbox Code Playgroud)
在GameController中我有这个构造函数
GameController(GameLayer*& GameLayer)
{
setGameLayer(gameLayer); // to GameLayer memeber )
}
Run Code Online (Sandbox Code Playgroud)
resone是我需要能够从GameController修改GameLayer中的数据(GUI的东西)
在书中的"C++ Concurrency in Action"§3.3.1中,在介绍使用类成员的线程安全延迟初始化时std::call_once(),它给出了以下示例:
#include <mutex>
struct connection_info
{};
struct data_packet
{};
struct connection_handle
{
void send_data(data_packet const&)
{}
data_packet receive_data()
{
return data_packet();
}
};
struct remote_connection_manager
{
connection_handle open(connection_info const&)
{
return connection_handle();
}
} connection_manager;
class X
{
private:
connection_info connection_details;
connection_handle connection;
std::once_flag connection_init_flag;
void open_connection()
{
connection=connection_manager.open(connection_details);
}
public:
X(connection_info const& connection_details_):
connection_details(connection_details_)
{}
void send_data(data_packet const& data)
{
std::call_once(connection_init_flag,&X::open_connection,this);
connection.send_data(data);
}
data_packet receive_data()
{
std::call_once(connection_init_flag,&X::open_connection,this);
return connection.receive_data();
}
};
int main()
{} …Run Code Online (Sandbox Code Playgroud) 是否有可能将std::function自己内部的一个替换为另一个std::function?
以下代码无法编译:
#include <iostream>
#include <functional>
int main()
{
std::function<void()> func = []()
{
std::cout << "a\n";
*this = std::move([]() { std::cout << "b\n"; });
};
func();
func();
func();
}
Run Code Online (Sandbox Code Playgroud)
可以对其进行修改以进行编译吗?
现在的错误消息是:此lambda函数未捕获“ this” -我完全理解。我不知道,但是,我怎么能抓住func的this终场。我想,这甚至不是std::function lambda里面了吗?如何才能做到这一点?
背景:我要实现的目标如下:在给定的第一次调用中std::function,我想做一些初始化工作,然后用优化的函数替换原始函数。我想为我的功能用户透明地实现这一目标。
上面的示例的预期输出为:
a
b
b
我偶然发现了这段代码来重新建立类不变式:
class Foo {
// some stuff in here
public:
void clear() {
*this = Foo();
//operator=(Foo()); // commented out in favor of the line above
}
};
Run Code Online (Sandbox Code Playgroud)
operator=是合法的并且可以按预期工作,但是在班级不动的情况下,将创建一个不必要的临时调用。因此,手动分配默认值可能会更有效,如果要扩展该类,则默认值将很麻烦且容易出错。*this = Foo(),如果允许的话,可能会更有效,因为我假设复制省略在这里可以工作(不管类是否可移动)。所以我的问题是:
*this = Foo();合法吗?如果是,请提供标准参考Foo是可移动的。(如果您认为这是骗子,请找我正确的问题,我什么也找不到)
this-pointer ×10
c++ ×7
c++11 ×3
pointers ×2
std-function ×2
byref ×1
c# ×1
c++17 ×1
constructor ×1
gcc ×1
ref ×1
this ×1
vb.net ×1