@Burnerr, zu deinem Einwand bezüglich des Pointers, es sollte vermutlich eher heißen "unique_ptr<klasse>*" wenn die Adresse dieses SmartPointer übergeben wurde - aber wie ich gerade sehe, verliert der Pointer seine "smarten" "Vor"typen, wenn man "get()" abruft, kann das sein?
Weil wenn ich anstelle dessen zum Beispiel nehme "&(*src_iter)" (also um das Objekt anzusprechen und die Adresse zu bekommen, ist es immer noch ein "unique_ptr<connection>*" nehme ich das "src_iter->get()" erhalte ich gleich die korrekte Addresse und muß es auch nicht zu einem "connection*" casten.
Also so 100% steige ich da noch nicht genau durch was da der genaue Unterschied ist zwischen (*item) und item->get() .
---
Ich muss auch dazu sagen, die Lambdas für "find_if" sehen auch sehr spannend aus, da würde ich lieber das Beispiel in einer anderen Funktion/Methode der Klasse(?) verwenden:
Wie hier gezeigt wird mit ein vector<int>:
http://www.cplusplus.com/reference/algorithm/find_if/
Also was das Lambda macht verstehe ich in etwa, aber die Syntax ist eine harte Nuss!
Achso und noch eine Kleinigkeit zum "const":
Ich lasse den Vector<connection*> jetzt per Adresse übergeben an die Funtionen die es benötigen, weil ich das "const" nicht direkt verwenden kann, sollte ja ressourcenschonender sein. Und es gibt generellen Schreibzugriff.
[src=cpp]vector<connection*>* getConnections() {
return &connections;
}[/src]
Und im Ctor einer connection wird jetz auch der Name gleich mit als parameter übertragen und direkt festgelegt.
Und hier mal der aktualisierte Quelltext, ich habe dort die Änderungen eingepflegt und auch sind noch removeConnection und removeLink dazu gekommen.... beide relativ identisch, bis auf den Unterschied das removeConnection per Adresse überprüft, währen removeLink mit "strings" arbeitet.
[src=cpp]#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
using namespace std;
//-------------------------------------------------------------------
class connection {
private:
string name;
vector<connection*> connections;
public:
connection(string newName) {
name = newName;
}
string getName() {
return name;
}
vector<connection*>* getConnections() {
return &connections;
}
bool addNodeLink(connection* nodeToConnect) {
for (connection* &node : connections) {
if (node == nodeToConnect) {
return false;
}
}
connections.push_back(nodeToConnect);
return true;
}
};
//-------------------------------------------------------------------
class connectionList_ {
private:
vector<unique_ptr<connection>> connectionList;
public:
connectionList_(){
};
bool addConnection(string name) {
for (unique_ptr<connection> &conn : connectionList) {
if (conn->getName() == name) {
cout << "Node \"" << name << "\" already present in connection list.";
return false;
}
}
/*
unique_ptr<connection> conn = make_unique<connection>();
conn->setName(name);
connectionList.push_back(move(conn));
*/
connectionList.push_back(make_unique<connection>(name));
cout << "Added connection \"" << name << "\" to connection list\n";
return true;
}
bool removeConnection(string targetName) {
vector<connection*>* sourceConnections;
vector<connection*>* targetConnections;
for (vector<unique_ptr<connection>>::iterator it = connectionList.begin(); it != connectionList.end(); ++it) {
if ((*it)->getName() == targetName) {
sourceConnections = (*it)->getConnections();
for (vector<connection*>::iterator itSource = (*sourceConnections).begin(); itSource != (*sourceConnections).end(); ++itSource) {
targetConnections = (*itSource)->getConnections();
for (vector<connection*>::iterator itTarget = (*targetConnections).begin(); itTarget != (*targetConnections).end(); ++itTarget) {
if (&(**it) == &(**itTarget)) {
(*sourceConnections).erase(itSource);
(*targetConnections).erase(itTarget);
--itSource;
--itTarget;
}
}
}
connectionList.erase(it);
cout << "Erased connection \"" << targetName << "\".\n";
return true;
}
}
cout << "Could not erase connection \"" << targetName << "\", item not found in connection list.\n";
return false;
}
bool removeLink(string srcName, string targetName) {
vector<connection*>* sourceConnections;
vector<connection*>* targetConnections;
for (vector<unique_ptr<connection>>::const_iterator it = connectionList.begin(); it != connectionList.end(); ++it) {
if ((*it)->getName() == srcName) {
sourceConnections = (*it)->getConnections();
for (vector<connection*>::const_iterator itSource = (*sourceConnections).begin(); itSource != (*sourceConnections).end(); ++itSource) {
if ((*itSource)->getName() == targetName) {
targetConnections = (*itSource)->getConnections();
for (vector<connection*>::const_iterator itTarget = (*targetConnections).begin(); itTarget != (*targetConnections).end(); ++itTarget) {
if (targetName == (*itSource)->getName()) {
(*sourceConnections).erase(itSource);
(*targetConnections).erase(itTarget);
cout << "Removed link \"" << targetName << "\" of \"" << srcName << "\".\n";
return true;
}
}
}
}
cout << "Remove link failed, target \"" << targetName << "\" not found in source \"" << srcName << "\".\n";
return false;
}
}
cout << "Remove link failed, source \"" << srcName << "\" not present.\n";
return false;
}
void listConnections(string name) {
if (connectionList.empty()) {
cout << "No objects in connection list.\n";
return;
}
for (unique_ptr<connection> &node:connectionList) {
if (node->getName() == name) {
cout << "\nLinks of \"" << name << "\" @ " << node.get() << endl;
for (connection* link
*node->getConnections())) {
cout << link->getName() << " @ " << link << endl;
}
return;
}
}
cout << "\"" << name << "\" is not present in connection list.\n";
}
bool linkConnections(string src, string dest) {
bool hasSource = false;
bool hasDestination = false;
const auto src_iter = find_if(
connectionList.begin(), connectionList.end(),
[&] (const unique_ptr<connection>& conn) {
if (conn->getName() == src) {
hasSource = true;
return true;
}
return false;
});
if (!hasSource) {
cout << "Item \"" << src << "\" not present for linking.\n";
return false;
}
const auto dest_iter = find_if(
connectionList.begin(), connectionList.end(),
[&] (const unique_ptr<connection>& conn) {
if (conn->getName() == dest) {
hasDestination = true;
return true;
}
return false;
});
if (!hasDestination) {
cout << "Item \"" << dest << "\" not present for linking.\n";
return false;
}
if ( (*src_iter)->addNodeLink(dest_iter->get()) && (*dest_iter)->addNodeLink(src_iter->get()) ) {
cout << "Added links from \"" << (*src_iter)->getName() << "\" to \"" << (*dest_iter)->getName() << "\"\n";
} else {
cout << "Link present, not adding: \"" << (*src_iter)->getName() << "\" to \"" << (*dest_iter)->getName() << "\"\n";
}
return true;
}
};
//-------------------------------------------------------------------
int main() {
connectionList_* connectionList = new connectionList_();
connectionList->listConnections("Object 4");
connectionList->addConnection("Object 1");
connectionList->addConnection("Object 2");
connectionList->listConnections("Object 4");
connectionList->addConnection("Object 3");
connectionList->addConnection("Object 4");
connectionList->linkConnections("Object 1", "Object 3");
connectionList->linkConnections("Object 1", "Object 3");
connectionList->linkConnections("Object 3", "Object 4");
connectionList->linkConnections("Object 2", "Object 4");
connectionList->linkConnections("Object 2", "Object 3");
connectionList->linkConnections("Object 5", "Object 3");
connectionList->listConnections("Object 1");
connectionList->listConnections("Object 2");
connectionList->listConnections("Object 3");
connectionList->listConnections("Object 4");
connectionList->listConnections("Object 2");
connectionList->removeLink("Object 2", "Object 3");
connectionList->listConnections("Object 2");
connectionList->removeConnection("Object 4");
connectionList->listConnections("Object 4");
connectionList->listConnections("Object 2");
delete connectionList;
return 0;
}
[/src]