473,657 Members | 2,595 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Storing objects in a vector

I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
I have the the following questions:

1). Why is the copy constructor called TWICE?
2). Why is the destructor called after mc has been pushed into the vector?
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?

- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al
Jul 23 '05 #1
12 3934
Alfonso Morra wrote:
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor, i.e., the number of calls to the first two
must balance with the destructor calls.


I have the the following questions:

1). Why is the copy constructor called TWICE? Not if I compile and run your program.
2). Why is the destructor called after mc has been pushed into the vector? Because push_back creates a copy.
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope? The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.

- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :
Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Cla ss*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al


Jul 23 '05 #2


Stephan Brönnimann wrote:
Alfonso Morra wrote:
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal() <<
endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " << mv[0].getVal()
<< endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !

Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor,


What does that mean in plain English ?

i.e., the number of calls to the first two must balance with the destructor calls.

Huh?

I have the the following questions:

1). Why is the copy constructor called TWICE?
Not if I compile and run your program.


Hmm ....

2). Why is the destructor called after mc has been pushed into the vector?
Because push_back creates a copy.


I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.

3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?


The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.


Once again, your response seems inconsistent. If the destructor of
"contained objects" is invoked, then - memory is being freed (this is
certainly true in the example I gave of contained object MyClass)
- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Cla ss*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.

This is axiomatic. I wanted to know *what* (if any) resource management
std::vector provides "out of the box", so I can decide if I need to
"roll my own" resource management logic.
i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?

Looking forward to some insightful answers. Many thanks

Al



Jul 23 '05 #3
Alfonso Morra wrote:
I have the ff code for testing the concept of storing objects:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "Default cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

MyClass( const MyClass& m) {
cout << "Copy cstor called !" << endl ;
this->i = new int ;
*(this->i) = *(m.i);
}

MyClass& operator=( const MyClass& m) {
cout << "Assignment called !" << endl ;
if (this != &m) {
MyClass tmp(m) ;
std::swap(this->i, tmp.i ) ;
}
return *this ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ;
cout << "Element 0 of the vector has i value : " << mv[0].getVal()
<< endl ;
cout << "Setting i value to 123\n" ;
mv[0].setVal(123) ;
cout << "Element 0 of the vector now has i value : " <<
mv[0].getVal() << endl ;
mv.clear() ;
cout << "(After clear) size of vector is : " << mv.size() << endl ;

return 0;
}
Here is output from the console (code execution point is at the point
where variable mc has been "pushed back" into the vector).

Default cstor called !
Copy cstor called !
Copy cstor called !
dstor called !
I have the the following questions:

1). Why is the copy constructor called TWICE?
Not sure. My implentation seems to make a temporary local copy, before copying it to where it will end up.
2). Why is the destructor called after mc has been pushed into the vector?
The temporary copy goes out of scope.
3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
Yes.
(ii) clear() is invoked
Should be equivelant to:
vec.erase(vec.b egin(), vec.end())
(iii) vector goes out of scope?
Yes.

But remember that if you use pointers to your objects, it is the pointers it both copies AND deletes, not the objects they point to.
- since a vector stores a copy of the item to be stored, it behooves me
to delete the original variables (the copies of which are stored in the
vector), since I do not want two copies, "floating about" and consuming
resources - maybe it would be better to store pointers to my object
instead in the vector?. Storing copies rather than the original items in
a vector seems quite an inefficient/expensive way of going about things
- i.e. :

i). Object creation
ii). Making a copy of the object (vector stores a copy not original)
iii). Deleting the original object (so only the copy in the vector is
kept) - to mimimise resource consumption

It just dosen't seem right ... deleting an object that has just been
created (purely for the purposes of making a copy) seems just plain
silly ... Please say it isn't so ...

What (if anything) am I missing?


The fact that copying probably isn't as expensive as you think, and that you shouldn't prematurely optimise.

You could use a reference counted pointer to store your objects if they really are that expensive to copy. Look at boost smart pointers:
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

Benchmark both approaches, but don't forget that something like a reference counted pointer introduces overhead too (counting when you copy, and indirection when you access)

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #4
Alfonso Morra wrote:


Stephan Brönnimann wrote:

Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor,

What does that mean in plain English ?


It means he didn;t read the bit that said you hadn't completed the program.
i.e., the number of calls to the first two
must balance with the destructor calls.


Huh?


In total, you should have 1 construction, 2 copies and 3 destructions.
I have the the following questions:

1). Why is the copy constructor called TWICE?

Not if I compile and run your program.

Hmm ....


I get two copies when compiled and run.

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #5


Ben Pope wrote:
Alfonso Morra wrote:


Stephan Brönnimann wrote:

>> Check again, the output above is wrong:
You trace all calls to constructors, assignment operator
and destructor,


What does that mean in plain English ?

It means he didn;t read the bit that said you hadn't completed the program.
i.e., the number of calls to the first two
must balance with the destructor calls.


Huh?

In total, you should have 1 construction, 2 copies and 3 destructions.
I have the the following questions:

1). Why is the copy constructor called TWICE?

Not if I compile and run your program.


Hmm ....

I get two copies when compiled and run.

Ben


Thanks for the clarification Ben. Your previous post was veery useful
also - atleast I know I'm not going mad (w.r.t to the copy constructor
being called twice :-) )

Jul 23 '05 #6


Alfonso Morra wrote:
Stephan Brönnimann wrote:
2). Why is the destructor called after mc has been pushed into the vector?
Because push_back creates a copy.


I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.


Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

3). Does the vector implementation guarantee that it will free my
(contained) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?


The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.


Once again, your response seems inconsistent. If the destructor of
"contained objects" is invoked, then - memory is being freed (this is
certainly true in the example I gave of contained object MyClass)


I your special case I agree, but that is because of ~MyClass()
and not because of the vector. Consider: what should happen
for std::vector<int >?

Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector<Cla ss*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.

This is axiomatic. I wanted to know *what* (if any) resource management
std::vector provides "out of the box", so I can decide if I need to
"roll my own" resource management logic.


std::vector manages its own allocated memory, that's it.
The memory management of the vector's content is up to you.

regards, Stephan

Jul 23 '05 #7


Stephan Brönnimann wrote:

Alfonso Morra wrote:
Stephan Brönnimann wrote:

2). Why is the destructor called after mc has been pushed into the vector?

Because push_back creates a copy.
I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.

Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

This is a typo. I meant to type "freed". By deleting the variable, I
meant any operation such as an erase, clear invokation on the vector,
that would cause an element to be deleted or erased (syntactic sugar)

3). Does the vector implementation guarantee that it will free my
(containe d) objects when:
(i) erase() is invoked
(ii) clear() is invoked
(iii) vector goes out of scope?

The destructor of the "contained objects" will be called,
no memory is freed by the vector except for the last case.


Once again, your response seems inconsistent. If the destructor of
"contained objects" is invoked, then - memory is being freed (this is
certainly true in the example I gave of contained object MyClass)

I your special case I agree, but that is because of ~MyClass()
and not because of the vector. Consider: what should happen
for std::vector<int >?

Please see my comment below
Think again: How whould you store the original item in the vector?
Could you provide the pseudo code for it?

If the copy construction of a class is expensive, you may use
std::vector< Class*> as STL-container, however then you'll need
to provide a wrapper class that takes care of copy, asssignment
and destruction of the vector.


This is axiomatic. I wanted to know *what* (if any) resource management
std::vector provides "out of the box", so I can decide if I need to
"roll my own" resource management logic.

std::vector manages its own allocated memory, that's it.
The memory management of the vector's content is up to you.

regards, Stephan


Jul 23 '05 #8
Alfonso Morra wrote:


Stephan Brönnimann wrote:

Alfonso Morra wrote:
Stephan Brönnimann wrote:
> 2). Why is the destructor called after mc has been pushed into the
> vector?

Because push_back creates a copy.

I dont understand the point you're making, creating a copy of a variable
is not the same as deleting the variable - in other words, the fact that
a copy is made of variable mc does not explain why it is fred.


Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

This is a typo. I meant to type "freed". By deleting the variable, I
meant any operation such as an erase, clear invokation on the vector,
that would cause an element to be deleted or erased (syntactic sugar)


I'm not sure what you think is syntactic suger. When you request for the copntainer to remove the element, the container will call the destructor of that item, and then remove
that item from the container and then deallocate any memory required to store that item. If that item is a pointer, and you allocated memory at the end of that pointer, thats
still your responsibility.

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #9


Ben Pope wrote:
Alfonso Morra wrote:


Stephan Brönnimann wrote:

Alfonso Morra wrote:

Stephan Brönnimann wrote:
>> 2). Why is the destructor called after mc has been pushed into the
>> vector?
>
>
> Because push_back creates a copy.
I dont understand the point you're making, creating a copy of a
variable
is not the same as deleting the variable - in other words, the fact
that
a copy is made of variable mc does not explain why it is fred.
Please be precise about the meaning of "deleting the variable" and
"fred".
Does it mean "the destructor of MyClass is called."
or does it mean "an object of MyClass is deleted?

This is a typo. I meant to type "freed". By deleting the variable, I
meant any operation such as an erase, clear invokation on the vector,
that would cause an element to be deleted or erased (syntactic sugar)

I'm not sure what you think is syntactic suger. When you request for
the copntainer to remove the element, the container will call the
destructor of that item, and then remove that item from the container
and then deallocate any memory required to store that item. If that
item is a pointer, and you allocated memory at the end of that pointer,
thats still your responsibility.

Ben


Thats not what I meant, (the term syntactic sugar being overloaded in
this particular usage) I was just being lazy and meant to say, the
phrases "deleting an object", "an objects destructor is called" are in
most cases, (certainly in this case) equivalent, and is largely a matter
of "syntax" (not in the computer language terminolgy sense).

Jul 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
2594
by: mjkahn | last post by:
I've read (and read!) that you shouldn't store objects in Session variables. I've read these reasons: - The object takes up memory that may not be freed until the session times out. Better to create the object only when you actually use it. - Causes poor performance because the thread that created the object has to service all requests for it. Assuming I can live with the memory and performance implications (a big if,
6
2564
by: Alfonso Morra | last post by:
I have written the following code, to test the concept of storing objects in a vector. I encounter two run time errors: 1). myClass gets destructed when pushed onto the vector 2). Prog throws a "SEGV" when run (presumably - attempt to delete deleted memory. Please take a look and see if you can notice any mistakes I'm making. Basically, I want to store classes of my objects in a vector. I also have three further questions:
4
1993
by: Frank Rizzo | last post by:
In classic ASP, it was considered a bad idea to store VB6-created objects in the Application variable for various threading issues. What's the current wisdom on storing objects in the Application variable in ASP.NET? I am thinking of storing several objects there, not too large, so there won't be any memory issues or anything like that. Is ASP.NET still subject to threading issues?
9
7287
by: david | last post by:
I have a class with some business-logic and with every roundtrip, I need an instance of this class, so I have to create it, every time again. That doesn't seem very efficient. I thought it would be 'better' to store an instance of this class in a session-variable, so it's available all the time and needs to be instanced only once. Is this, generally speaking, a good idea, storing objects in session-variables ? Do you guys ever use this...
1
2169
by: Miesha.James | last post by:
Hello, I'm trying to rewrite visual c++ code into visual c++ .NET code and I've run across a problem with storing objects into a list. Here;s an example of the code I have: ref struct Cookies { String^ Name;
13
2798
by: r.z. | last post by:
I logged construtor and destructor calls for one of my classes and I discovered that the constructor was called only once while the destructor was called 3 times for a single object. I have a vector of objects of class A: vector<Avector_of_As; and I put objects to it like this: vector_of_As.push_back( A() );
3
1387
by: Bruno.DiStefano | last post by:
Hi All, BACKGROUND INFO I need to use a "vector" structure to store a number of objects that becomes known only at run time. The constructor, at instantiation time of a new object, increments a static counter. The value of this counter becomes the ID of the object that has just been instantiated. I am using Visual C++ 6.0 and, for this project, in the short term I have no options about this.
4
1467
by: alexjcollins | last post by:
The following program demonstrates the problem: #include <vector> #include <iostream> #include <tvmet/Vector.h> typedef tvmet::Vector<double, 3Vector3d; class Mesh {
0
8397
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8827
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8503
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8605
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7333
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5632
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4158
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4315
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1957
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.