Соблюдайте следующий код:
class A { public: virtual void Foo() = 0; int Bar; };
class B : public A { public: B( float X ); void Foo(); private: float X; };
class C : public A { public: C( float Y ); void Foo(); private: float Y; };
Теперь, в некоторой функции, скажем, я делаю это:
A*& pToA = pToDerived; // allocated as A* pToDerived = new B( ... );
pToA = pToC; // allocated as A* pToC = new C( ... );
Это действительно? Если это так, это приведет к утечке памяти, хотя pToA
ссылка на указатель pToDerived
?
SSCS
Предположим, что Node
имеет, скажем, 2 или более типов, которые происходят от него. Это фрагмент из связанного списка, который я сейчас реализую, для корректной работы которого, скорее всего, потребуется полиморфизм, поскольку он не должен быть универсальным. newnode
аргумент, переданный функции вставки.
Node* iNode;
for( iNode = mStart; iNode != mEnd; iNode = iNode->Next )
{
if ( iNode->Key == k ) // Replace current node with newnode
{
newnode->Next = iNode->Next;
newnode->Prev = iNode->Prev;
*iNode = *newnode;
delete newnode;
return; // We're done, so we quit.
}
}
// Node doesn't alreay exist, so we add it.
Node*& uglyhack = mEnd;
iNode->Next = newnode;
newnode->Prev = iNode;
uglyhack = newnode;
Допустим, у вас есть следующее:
// See http://codepad.org/8mG6YiLy
class A { public: virtual void Foo() = 0; int Bar; };
// Added definitions for these so that this would compile
class B : public A {
public: B( float x ) : X(x) {}
virtual void Foo() {} // Once virtual, always virtual
private: float X;
};
class C : public A {
public: C( float y ) : Y(y) {}
virtual void Foo() {}
private: float Y;
};
int main()
{
A* pToDerived = new B(3.14);
// pToDerived -> B
A*& pToA = pToDerived;
// pToDerived -> B
// pToA IS pToDerived
A* pToC = new C(2.718);
// pToDerived -> B
// pToC -> C
// pToA IS pToDerived
pToA = pToC;
// pToDerived -> C
// pToC -> C
// pToA IS pToDerived
// One object of type B no longer has pointers pointing to it
}
Этот код пропускает два объекта — один из типа B
(что происходит на pToA = pToC
заявление) и один из типа C
(что происходит, когда main
возвращается). «Ссылка» в данном случае на самом деле не играет большой роли. В C ++ ссылки являются просто псевдонимами для некоторого другого объекта. Вы не можете «переустановить» их. То есть, если ссылка ссылается на что-то, она никогда больше не может ссылаться на что-либо еще.
В этом случае, когда вы создали pToA, вы создали ссылку на указатель — указатель в этом случае pToDerived
, Создание этой ссылки не влияет на управление памятью или ответную реакцию некоторого кода на вызов delete
в нужном месте вообще.
Это то же самое, что делать
pToDerived = pToC;
В этом нет ничего плохого. Это приведет к утечке памяти, только если вы никогда не удалите объекты, как обычно.
В своем обновленном коде вы можете просто сделать:
iNode->Next = newnode;
newnode->Prev = iNode;
mEnd = newnode;
и было бы то же самое.