i really dont understand the following behavior:
3 Code snippets to explain
sqlconnection.h
class SqlConnection
{
public:
SqlConnection();
QSqlDatabase db;
} ;
sqlconnection.cpp
SqlConnection::SqlConnection()
{ if (!db.open()){ //no different with or without that
db = QSqlDatabase::addDatabase("QODBC");
...
}
artikelverwaltung.cpp
Artikelverwaltung::Artikelverwaltung(){
SqlConnection().db.open();
...(code to do works fine)
}
void Artikelverwaltung::on_pushButton_2_clicked()
{
SqlConnection().db.close(); // "HERE"
}
"HERE" it cycles the full Contructor of the Class again, but why it don't just close the connection? (this is the Main question about and how to fix that.)
I can't even access "db" from another Method inside the Class but outside of the Constructor, like:
sqlconnection.cpp:
void closeDB() {db.close();} is not possible.`
What i am doing wrong?
Thank you guys
In general, you do not need to use any wrapper class to hold database connections in Qt. You should create a database connection once using QSqlDatabase::addDatabase and open it. After that you can get a database connection anywhere by calling QSqlDatabase::database static method. So to close the database connection you should simply call QSqlDatabase::database().close().
Hello and welcome to Stackoverflow!
If you call SqlConnection().db.close();, what you are actually doing is creating a new instance of your SqlConnection class and then calling close() on its variable db. This is not the same one you opened earlier.
What you want to do is inside of your Artikelverwaltung class:
SqlConnection sqlConnection = new SqlConnection();
and then later
sqlConnection.db.open();
and afterwards
sqlConnection.db.close();
The reason why you cant add that closeDB() method is that you need to either put the method inside of the SqlConnection class or you need to operate on an instance of the class.
You cannot operate on a class like this without instanciating it (creating an instance of it).
You should look at class instantiation to understand how the concept works.
If you call SqlConnection() you are creating a new instance of the class (you can look at it like a copy of the class).
If you call SqlConnection() somewhere else you are simply creating a new instance.
These instances do NOT share the variables or the contents in them. They are completely independent.
You cannot access a member of a class (like your db variable) without creating an instance of the class first and then accessing the member of that instance.
Related
What I was doing before was that I was calling a function of my interface and it determinate in a switch condition thanks to a parameter what to do with the data. What kind of specialization they have.
But now, what I am trying to create a local object, treat it, and then add it to my containers of the interface.
In order to do that I have to copy all the value of my local object (which have been treated) in my container of the interface.
So I created a copy_cell function in the interface, a virtual one, and one in the subclass. But whenever I try to do it the interface function is called and not the subfunction.
GridCell_voxel * local_cell;
local_cell = new GridCell_voxel(m_grid_map( cell2matindex_x(cell_index_x), cell2matindex_y(cell_index_y))->getVoxelResolution(), m_grid_map( cell2matindex_x(cell_index_x), cell2matindex_y(cell_index_y))->getVoxel().size());
local_cell->process_points(relevant_points, m_mapping_type);
//This is the line I need to change
local_cell->copy_cell (m_grid_map( cell2matindex_x( cell_index_x), cell2matindex_y( cell_index_y))) ;
Do you have any idea on the way to go? What am I missing here?
Sorry for the lack of information, i will try to expose how i managed and what i was actually looking for.
So i have a container of IntefaceCell, called m_grid_map, full of cell that has been specialized. In my case m_grid_map is full of GridCell_voxel which is a sub class from InterfaceCell.
What i want to do is, create a new local GridCell_voxel, copy the information in it. Then process the informations, then copy the local cell in the container.
The important part is the dynamic_cast in the copy cell function, which allow you to take an InterfaceCell as argument and then treat it as GridCell_voxel.
//Main.cpp
GridCell_voxel * local_cell;
local_cell = new GridCell_voxel();
local_cell->copy_cell (m_grid_map( cell2matindex_x( cell_index_x), cell2matindex_y( cell_index_y)));
local_cell->process_points(relevant_points, m_mapping_type);
m_grid_map( cell2matindex_x( cell_index_x), cell2matindex_y( cell_index_y))->copy_cell (local_cell);
delete local_cell;
//GridCell_voxel.cpp
void GridCell_voxel::copy_cell(GridCellInterface* cell) {
GridCell_voxel* voxel_cell = dynamic_cast<GridCell_voxel*>(cell);
this->m_voxel_start_height = voxel_cell->m_voxel_start_height;
this->init = true;
this->m_ground_voxel_position = voxel_cell->m_ground_voxel_position;
}
I hope it will help someone.
If a page or component class has one instance field which is a non-synchronized object, f.ex. an ArrayList, and the application has code that structurally modifies this field, should the access to this field be synchronized ?
F.ex.:
public class MyPageOrComponent
{
#Persist
private List<String> myList;
void setupRender()
{
if (this.myList == null)
{
this.myList = new ArrayList<>();
}
}
void afterRender(MarkupWriter writer)
{
// Should this be synchronized ?
if (someCondition)
{
this.myList.add(something);
}
else
{
this.myList.remove(something);
}
}
}
I'm asking because I seem to understand that Tapestry creates only one instance of a page or component class and it uses this instance for all the connected clients (but please correct me if this is not true).
In short the answer is no, you don't have to because Tapestry does this for you. Tapestry will transform your pages and classes for you at runtime in such a way that wherever you interact with your fields, they will not actually be working on the instance variable but on a managed variable that is thread safe. The full inner workings are beyond me, but a brief reference to the transformation can be found here.
One warning, don't instantiate your page/component variables at decleration. I have seen some strange behaviour around this. So don't do this:
private List<String> myList = new ArrayList<String>;
Tapestry uses some runtime byte code magic to transform your pages and components. Pages and components are singletons but the properties are transformed so that they are backed by a PerThreadValue. This means that each request gets it's own copy of the value so no synchronization is required.
As suggested by #joostschouten you should never initialize a mutable property in the field declaration. The strange behaviour he discusses is caused beacause this will be shared by all requests (since the initializer is only fired once for the page/component singleton). Mutable fields should instead be initialized in a render method (eg #SetupRender)
I got the following problem:
I made a custom list CustomList which extends ArrayList and added a new method to it:
public class CustomList extends ArrayList<CustomObj> {
public CustomObj get(String searchName) {
...
}
}
now in my MainActivity.java I make a new object of this CustomList, but I'm using:
List<CustomObj> list = new CustomList(); (1)
and NOT:
CustomList list = new CustomList(); (2)
so far so good!
but when I try to access the function get(String searchName), there is no function I could use!
why? cause when I call it when creating the CustomList via (2) it'll totally work
its is because you are making List(Interface) has no any such method defined , you are making object of CustomList but reference type is List .so it will give you compile time errer if you force to call this method on List reference.This is an example of simple Polymorphism.
You can imagine a case where Mordern car extends Old age car and mordern car has GPS navigation system where as old doesn't in this case if you try to get the detail of navigation system by old car reference which doesn't know about GPS , you wont get anything.
I have a TcpDevice class which encapsulates a TCP connection, which has an onRemoteDisconnect method which gets called whenever the remote end hangs up. Then, there's a SessionManager object which creates TcpSession objects which take a TcpDevice as a communication channel and inserts them in an internal pointer container for the application to use. In case any of the managed TcpSessions should end, I would like the SessionManager instance to be notified about it and then remove the corresponding session from the container, freeing up the resources associated with it.
I found my problem to be very similar to this question:
Object delete itself from container
but since he has a thread for checking the connections state, it gets a little different from mine and the way I intended to solve it using boost::signals, so I decided to go for a new question geared towards it - I apologize if it's the wrong way to do it... I'm still getting the feel on how to properly use S.O. :)
Since I'm kind of familiar with QT signals/slots, I found boost::signals offers a similar mechanism (I'm already using boost::asio and have no QT in this project), so I decided to implement a remoteDeviceDisconnected signal to be emitted by TcpDevice's onRemoteDisconnect, and for which I would have a slot in SessionManager, which would then delete the disconnected session and device from the container.
To initially try it out I declared the signal as a public member of TcpDevice in tcpdevice.hpp:
class TcpDevice
{
(...)
public:
boost::signal <void ()> remoteDeviceDisconnected;
(...)
}
Then I emitted it from TcpDevice's onRemoteDisconnect method like this:
remoteDeviceDisconnected();
Now, is there any way to connect this signal to my SessionManager slot from inside session manager? I tried this:
unsigned int SessionManager::createSession(TcpDevice* device)
{
unsigned int session_id = session_counter++;
boost::mutex::scoped_lock lock(sessions_mutex);
sessions.push_back(new TcpSession(device, session_id));
device->remoteDeviceDisconnected.connect(boost::bind(&SessionManager::removeDeadSessionSlot, this));
return session_id;
}
It compiles fine but at link time it complains of multiple definitions of remoteDeviceDisconnected in several object code files:
tcpsession.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected'
tcpdevice.cpp.o: (.bss+0x0): first defined here
sessionmanager.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected'
tcpdevice.cpp.o: (.bss+0x0): first defined here
I found this strange, since I didn't redefine the signal anywhere, but just used it at the createSession method above.
Any tips would be greatly appreciated! Thank you!
My bad! Like we all should expect, the linker was right... there was indeed a second definition, I just couldn't spot it right away because it wasn't defined by any of my classes, but just "floating" around one of my .cpp files, like those found on boost::signals examples.
Just for the record, the initial idea worked like a charm: when a given TcpDevice gets disconnected from the remote end, it emits the remoteDeviceDisconnected signal, which is then caught by the SessionManager object which holds the TcpSession instance that points to that TcpDevice. Once notified, SessionManager's method removeDeadSessionSlot gets executed, iterating through the sessions ptr_list container and removing the one which was disconnected:
void SessionManager::removeDeadSessionSlot()
{
boost::mutex::scoped_lock lock(sessions_mutex);
TcpSession_ptr_list_it it = sessions.begin();
while (it != sessions.end()) {
if (!(*it).device->isConnected())
it = sessions.erase(it);
else
++it;
}
}
Hope that may serve as a reference to somebody!
I have three files:
ScriptProcessor.java:
public interface ScriptProcessor {
public String someMethod();
}
ScriptProcessorDummy.java:
public class ScriptProcessorDummy implements ScriptProcessor {
public String someMethod{
return "some string";
}
}
In the main method, the code does the following:
URLClassLoader loader = null;
loader = new URLClassLoader(new URL[] {new URL("JARFILE")});
if (loader != null) {
ScriptProcessor processor = (ScriptProcessor) loader.loadClass("ScriptProcessorDummy").newInstance();
}
"JARFILE" contains class files of ScriptProcessor and ScriptProcessorDummy.
The code works fine when using JDK 1.4 but when using JDK 1.5, the typecast (to ScriptProcessor) fails with java.lang.ClassCastException.
Could somebody please tell me how to fix this.
Thanks,
Raj
You need to make your current class loader the parent of the new class loader you are loading, and make sure that there isn't a copy of the interface in your jar.
The problem you have suggests that you have two copies of the interface: one in the main class loader, one in your new one. The object returned uses the one in the separate jar, but your class is using the main one. They aren't the same. You have to make sure that Java uses the same '.class' for the interface when processing the loaded class as it did when it compiled your code.
The first thing to do is 'jar tf' on the jar and see if my hypothesis of two copies is correct. If so, remove it. Try running. If you now get a NoClassDef, fix the construction of the loader.
new URLClassLoader(urlArray, Thread.currentThread().getContextClassLoader());
assuming that your environment maintains the context class loader. Alternatively,
new URLClassLoader(urlArray, ScriptProcessor.class.getClassLoader());
Try using:
loader.loadClass("ScriptProcessorDummy", true).newInstance();
the boolean tell the classloader to resolve the class name.