我目前正在尝试学习如何使用智能指针.然而,在做一些实验时,我发现了以下情况,我无法找到一个令人满意的解决方案:
想象一下,你有一个A类的对象是B类对象(孩子)的父对象,但两者都应该互相认识:
class A;
class B;
class A
{
public:
void addChild(std::shared_ptr<B> child)
{
children->push_back(child);
// How to do pass the pointer correctly?
// child->setParent(this); // wrong
// ^^^^
}
private:
std::list<std::shared_ptr<B>> children;
};
class B
{
public:
setParent(std::shared_ptr<A> parent)
{
this->parent = parent;
};
private:
std::shared_ptr<A> parent;
};
Run Code Online (Sandbox Code Playgroud)
问题是A类的一个对象如何std::shared_ptr
将自身(this
)传递给它的孩子?
有Boost共享指针(Get a boost::shared_ptr
forthis
)的解决方案,但是如何使用std::
智能指针处理这个问题?
'this'指针究竟存储在内存中的哪个位置?它是在堆栈,堆中还是在数据段中分配的?
#include <iostream>
using namespace std;
class ClassA
{
int a, b;
public:
void add()
{
a = 10;
b = 20;
cout << a << b << endl;
}
};
int main()
{
ClassA obj;
obj.add();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我调用成员函数add()
,接收器对象隐式传递为'this'指针.凡被this
存储在内存中?
我问自己this
指针是否可能被过度使用,因为我通常在每次引用成员变量或函数时都使用它.我想知道它是否会产生性能影响,因为必须有一个指针需要每次都被解除引用.所以我写了一些测试代码
struct A {
int x;
A(int X) {
x = X; /* And a second time with this->x = X; */
}
};
int main() {
A a(8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,即使-O0
他们输出完全相同的汇编程序代码.
此外,如果我使用成员函数并在另一个成员函数中调用它,它会显示相同的行为.那么this
指针只是编译时间而不是实际指针吗?或者是否存在this
实际翻译和解除引用的情况?我使用GCC 4.4.3 btw.
正如标题中所提到的,我想知道'this'
指针的类型.
我正在研究一个项目,我发现'this'
指针的类型是"ClassName * const this"
在使用VC++ 2008的Windows上.我想知道是什么需要/要求使这个指针成为一个常量指针.谢谢.
我发现this
在lambda 中捕获的示例显式使用了它。例如:
capturecomplete = [this](){this->calstage1done();};
Run Code Online (Sandbox Code Playgroud)
但是似乎也可以隐式使用它。例如:
capturecomplete = [this](){calstage1done();};
Run Code Online (Sandbox Code Playgroud)
我在g ++中对此进行了测试,并对其进行了编译。
这是标准的C ++吗?(如果可以,是哪个版本),还是某种扩展形式?
在该this
指针 [class.this],C++标准规定:
类的
this
成员函数的类型X
是X*
.
即this
不是const
.但那为什么呢
struct M {
M() { this = new M; }
};
Run Code Online (Sandbox Code Playgroud)
给
error: invalid lvalue in assignment <-- gcc
'=' : left operand must be l-value <-- VC++
'=' : left operand must be l-value <-- clang++
'=' : left operand must be l-value <-- ICC
(source: some online compiler frontends)
Run Code Online (Sandbox Code Playgroud)
换句话说,this
不是const
,但它确实是!
返回对此对象的引用通常用于赋值运算符重载.它还用作命名参数idiom的基础,它允许通过对setter方法的调用链初始化对象:Params().SetX(1).SetY(1)
每个都返回对*this的引用.
但是返回引用是否正确*this
.如果我们调用该方法为临时对象返回对此的引用,该怎么办:
#include <iostream>
class Obj
{
public:
Obj(int n): member(n) {}
Obj& Me() { return *this; }
int member;
};
Obj MakeObj(int n)
{
return Obj(n);
}
int main()
{
// Are the following constructions are correct:
std::cout << MakeObj(1).Me().member << std::endl;
std::cout << Obj(2).Me().member << std::endl;
Obj(3).Me() = Obj(4);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我收到这个奇怪的错误:
错误C2663:'sf :: Drawable :: SetPosition':2个重载没有'this'指针的合法转换
我认为它与const不匹配有关,但我不知道在哪里或为什么.在下面的代码中,我有一个形状和精灵的向量,当试图访问其中一个向量形状并调用其中一个函数时,我得到了错误.
std::vector<sf::Shape> Shapes;
std::vector<sf::Sprite> Sprites;
bool AddShape(sf::Shape& S){
Shapes.push_back(S); return true;
};
bool AddSprite(sf::Sprite& S){
Sprites.push_back(S); return true;
};
private:
virtual void Render(sf::RenderTarget& target) const {
for(unsigned short I; I<Shapes.size(); I++){
Shapes[I].SetPosition(
Shapes[I].GetPosition().x + GetPosition().x,
Shapes[I].GetPosition().y + GetPosition().y);
target.Draw(Shapes[I]);
}
for(unsigned short I; I<Sprites.size(); I++){
target.Draw(Sprites[I]);
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
这个早期的问题询问this[0]
C#中的含义.在C++中,this[0]
意思是"指向的数组的第0个元素this
".
是否保证不会在C++中导致未定义的行为以这种方式引用接收器对象?我并不主张使用这种语法,并且我很好奇这个规范是否能保证它始终有效.
谢谢!
我有一个与磁盘上存储的某些文件相关的对象。该对象的构造函数接受该文件作为参数,读取它并根据文件内容的设置创建一个实际对象。在运行时该文件有可能被用户修改。该对象有一个方法来检查文件自上次读取以来是否已被修改,如果是这样,则必须更新该对象。对象内部有足够的成员需要更新,因此无需手动更新每个成员,只需创建一个新对象并将其移动到现有对象中会更方便(更少的键入和更好的可读性)。*this
但在方法执行期间进行更改实际上是否安全,如下例所示?
void Object::update()
{
if (this->isModified(file)) // Check if a file has been modified since the last read
{
try
{
Object newObject(file); // May throw
*this = std::move(newObject); // Is it safe?
}
catch (const std::exception& ex)
{
// Invalidate and rethrow exception
this->invalidate();
throw(ex);
}
}
// ...
}
Run Code Online (Sandbox Code Playgroud)