Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
|
03-11-2004, 06:23 PM
|
#1
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Rep:
|
Builtin operator overloading.
I need to overload the >> operator for a rational number type, up till now I have always made the overloading function into a "friend" function, I do not like this and do not want it to be a friend anymore.
I simply removed the friend keyword from the function declaration and placed the function into the rational number type, here are code snippets:
class RatNum
{
//constructors and such
istream& operator >>(istream& ins, RatNum& InRat);
}
istream& RatNum::operator >>(istream& ins, RatNum& InRat)
{
//stuff
}
I get this error:
assign10.cpp:66: `std::istream& RatNum::operator>>(std::istream&, RatNum&)'
must take exactly one argument
assign10.cpp:289: `std::istream& RatNum::operator>>(std::istream&, RatNum&)'
must take exactly one argument
I am guessing it means I can have only one argument, as that is what it says, but would that mean it takes the >> function from the right hand side? I would think it would take the operator function (if it is overloaded) from the left hand side meaning it would use the wrong function since it needs to use the one specified for the right hand side. or would it try and see if the right hand side overloads the operator?
Last edited by exodist; 03-11-2004 at 06:30 PM.
|
|
|
03-11-2004, 06:29 PM
|
#2
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
Testing on my own..
to test I changed the internal function to:
class RatNum
{
istream& operator >>(istream& ins);
}
istream& RatNum::operator >>(istream& ins)
{
//stuff
}
and made a tester:
int main()
{
RatNum Bob;
cin >> Bob;
cout << Bob.GetNumer() << "/" << Bob.GetDenom();
return 0;
}
on compile I got this nasty message:
assign10.cpp: In function `int main()':
assign10.cpp:80: no match for `std::istream& >> RatNum&' operator
/usr/include/c++/3.2.3/bits/istream.tcc:83: candidates are:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(std::basic_istream<_CharT,
_Traits>&(*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char,
_Traits = std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:92:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(std::basic_ios<_CharT,
_Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits
= std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:101:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(std::ios_base&(*)(std::ios_base&)) [with _CharT = char,
_Traits = std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:110:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(bool&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:137:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(short int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:174:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(short unsigned int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:201:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:238:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(unsigned int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:265:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(long int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:292:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(long unsigned int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:320:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(long long int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:347:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(long long unsigned int&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:375:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(float&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:402:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(double&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:429:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(long double&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:456:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(void*&) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.2.3/bits/istream.tcc:483:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::operator>>(std::basic_streambuf<_CharT, _Traits>*) [with _CharT =
char, _Traits = std::char_traits<char>]
/usr/include/c++/3.2.3/istream:236: std::basic_istream<char,
_Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned
char&) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.3/istream:241: std::basic_istream<char,
_Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char&)
[with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.3/istream:250: std::basic_istream<char,
_Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned
char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.2.3/istream:255: std::basic_istream<char,
_Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char*)
[with _Traits = std::char_traits<char>]
|
|
|
03-11-2004, 06:29 PM
|
#3
|
LQ Guru
Registered: Feb 2003
Location: Colorado Springs, CO
Distribution: Gentoo
Posts: 2,018
Rep:
|
I'm not certain, but I think that the >> and << operators must be declared outside the class, and made friend functions. Those operators are actually members of the stream class, and are called by a stream object (like cin, cout, a file stream, etc.), so what you're really doing is overloading a stream class function to teach it how to write out (or read in) objects of your RatNum class. I'm not sure why that would give "exactly one argument" errors, though...
Edit: I think I may be wrong about the operators being members of a stream class... been a while since I studied them.
|
|
|
03-11-2004, 06:34 PM
|
#4
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
that doesn't quite make sence, what if you creade an adt in a seperate chared library and want a program to use it with >> operators overloaded, wouldn't you have to place the friend function code into each program that uses the library, and if I am not mistaken doesn't that defeat the purpose of shared libraries?
|
|
|
03-11-2004, 07:29 PM
|
#5
|
Member
Registered: Jul 2003
Location: VA Tech
Distribution: Mandrake 9.1
Posts: 73
Rep:
|
Ok I dug up this code from an old project:
ostream &operator<<(ostream &os,log_entry &entry)
{
os<<DASH_LINE<<"\n";
os<<entry.get_log_number()<<":";
os<<"Command: "<<entry.get_command()<<" , "<<entry.get_argument()<<"\n";
os<<" Results:"<<" "<<entry.get_first_result()<<"\n";
while(entry.move_next_result())
{
os<<" "<<entry.get_next_result()<<"\n";
}
os<<"Command: ";
if(entry.get_status_of())
{
os<<"Successful"<<"\n";
}
else
os<<"Failed"<<"\n";
return os;
}
this is a << operator overload but the syntax is the same for the >> operator.
It is defined within the cpp file of the log_entry class. It is not a member function and this prototype was included in the .h file for the log_entry class.
class log_entry;
ostream &operator<<(ostream &os,log_entry &entry);
incase you are unfamiliar with this "class log_entry;" line it is a foward declaration which allows you to declare the prototype to the global function with the class as an argument before the class is defined.
Hope it helps
|
|
|
03-11-2004, 07:45 PM
|
#6
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
ok, also I think the operator& operator as reference may be what I was missing for the most part, thanx I will try this out when I have a chance
|
|
|
03-11-2004, 07:50 PM
|
#7
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
I am now very confused, cause I did it with the &operator<< and it worked as a member function. then I tried removing the & for giggles... it still worked! so I am doing it just like before and it is working, something else must have been problem. I had finished everything as friend then changed it to member and no problems.. hmm
|
|
|
03-11-2004, 07:55 PM
|
#8
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
I feel like a Dumbass, I did the test for the member function in another file but continued to use old one, so it is still nto working :-P
|
|
|
03-11-2004, 08:14 PM
|
#9
|
Member
Registered: Jul 2003
Location: VA Tech
Distribution: Mandrake 9.1
Posts: 73
Rep:
|
Quote:
Originally posted by exodist
I feel like a Dumbass, I did the test for the member function in another file but continued to use old one, so it is still nto working :-P
|
Show me what you have now.
|
|
|
03-11-2004, 08:21 PM
|
#10
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
class RatNum
{
public:
RatNum(int Num, int Den);
RatNum(int Num);
RatNum(double Dec);
RatNum();
int GetNumer();
int GetDenom();
double GetDec();
void SetNumer(int Num);
void SetDenom(int Den);
void SmallDen();
RatNum operator +(const RatNum& InRatL, const RatNum& InRatR);
RatNum operator -(const RatNum& InRatL, const RatNum& InRatR);
RatNum operator -(const RatNum& InRat);
RatNum operator *(const RatNum& InRatL, const RatNum& InRatR);
RatNum operator /(const RatNum& InRatL, const RatNum& InRatR);
bool operator ==(const RatNum& InRatL, const RatNum& InRatR);
bool operator <=(const RatNum& InRatL, const RatNum& InRatR);
bool operator >=(const RatNum& InRatL, const RatNum& InRatR);
bool operator <(const RatNum& InRatL, const RatNum& InRatR);
bool operator >(const RatNum& InRatL, const RatNum& InRatR);
istream& operator >>(istream& ins, RatNum& InRat);
ostream& operator <<(ostream& outs, RatNum& InRat);
private:
void normalize(); // This function calculates the value for the fraction in double form, it also ensures the denominator is positive, and it reduces the fraction.
int Numer;
int Denom;
};
int main()
{
cout << endl << "Please type a rational number (#/# ex: 1/2)" << endl;
cout << "Rational Number:";
RatNum Test1;
cin >> Test1;
cout << endl << "You Typed:"<< Test1.GetNumer() << "/" << Test1.GetDenom() << endl << endl;
cout << "Testing << of Test1:" << Test1 << endl << endl;
RatNum Large(99,100);
RatNum Small(1,100);
RatNum Half1(1,2);
RatNum Half2(1,2);
cout << "Test Numbers: " << Large << " : " << Small << " : " << Half1 << " : " << Half2 << endl;
//-----------------------------
if (Half1 == Half2)
{
cout << "Test1 Success" << endl;
}
else
{
cout << "Test1 Fail!" << endl;
}
if (Large == Small)
{
cout << "Test2 Fail!" << endl;
}
else
{
cout << "Test2 Success" << endl;
}
//-----------------------------
//-----------------------------
if (Half1 <= Half2)
{
cout << "Test3 Success" << endl;
}
else
{
cout << "Test3 Fail!" << endl;
}
if (Large <= Small)
{
cout << "Test4 Fail!" << endl;
}
else
{
cout << "Test4 Success" << endl;
}
//-----------------------------
//-----------------------------
if (Half1 >= Half2)
{
cout << "Test5 Success" << endl;
}
else
{
cout << "Test5 Fail!" << endl;
}
if (Large >= Small)
{
cout << "Test6 Success" << endl;
}
else
{
cout << "Test6 Fail!" << endl;
}
//-----------------------------
//-----------------------------
if (Half1 < Half2)
{
cout << "Test7 Fail!" << endl;
}
else
{
cout << "Test7 Success" << endl;
}
if (Large < Small)
{
cout << "Test8 Fail!" << endl;
}
else
{
cout << "Test8 Success" << endl;
}
//-----------------------------
//-----------------------------
if (Half1 > Half2)
{
cout << "Test9 Fail!" << endl;
}
else
{
cout << "Test9 Success" << endl;
}
if (Large > Small)
{
cout << "Test10 Success" << endl;
}
else
{
cout << "Test10 Fail!" << endl;
}
//-----------------------------
RatNum ROne(2,10);
RatNum RTwo(1,10);
cout << ROne << " : " << RTwo << endl;
RatNum Add = ROne + RTwo;
cout << Add << endl;
RatNum Sub = ROne - RTwo;
cout << Sub << endl;
RatNum Mul = RTwo * ROne;
cout << Mul << endl;
Mul = 2 * ROne;
cout << Mul << endl;
RatNum Div = ROne / 2;
cout << Div << endl;
Div = ROne / RTwo;
cout << Div << endl;
return 0;
}
//-------------Functions for RatNum------------
RatNum::RatNum(int Num, int Den)
{
Numer = Num;
Denom = Den;
normalize();
}
RatNum::RatNum(int Num)
{
Numer = Num;
Denom = 1;
normalize();
}
RatNum::RatNum(double Dec)
{
Numer = static_cast<int>(Dec * 100); // 2 decimal places should be enough
Denom = 100;
normalize();
}
RatNum::RatNum()
{
Numer = 0;
Denom = 1;
normalize();
}
int RatNum::GetNumer()
{
return Numer;
}
int RatNum::GetDenom()
{
return Denom;
}
double RatNum::GetDec()
{
return (static_cast<double>(Numer)/static_cast<double>(Denom));
}
void RatNum::SetNumer(int Num)
{
Numer = Num;
normalize();
}
void RatNum::SetDenom(int Den)
{
Denom = Den;
normalize();
}
void RatNum::SmallDen() // change to smallest denominator
{
int counter = 9;
int pass = 1;
while (counter > 1)
{
if (((Numer%counter) == 0) && ((Denom%counter) == 0))
{
Numer = Numer/counter;
Denom = Denom/counter;
}
counter--;
if ((counter == 1) && (pass == 1))
{
counter = 9;
pass = 2;
}
}
}
void RatNum::normalize()
{
SmallDen();
if (Denom < 0)
{
Denom = (Denom * (-1)); // Ensure denominator is positive
}
}
istream& RatNum::operator >>(istream& ins, RatNum& InRat)
{
int TNum, TDen;
char TempChar;
bool Negative = false;
ins >> TempChar;
if (TempChar == '-')
{
Negative = true;
}
else
{
ins.putback(TempChar);
}
ins >> TNum >> TempChar >> TDen;
if (Negative)
{
TNum *= (-1);
}
InRat.Numer = TNum;
InRat.Denom = TDen;
InRat.normalize();
return ins;
}
ostream& RatNum::operator <<(ostream& outs, RatNum& InRat)
{
outs << InRat.Numer << "/" << InRat.Denom;
return outs;
}
RatNum RatNum::operator +(const RatNum& InRatL, const RatNum& InRatR)
{
RatNum OutRat;
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
int NewNumer = ((I2Numer * IDenom) + (INumer * I2Denom));
int NewDenom = (I2Denom * IDenom);
OutRat = RatNum(NewNumer,NewDenom);
return OutRat;
}
RatNum RatNum::operator -(const RatNum& InRatL, const RatNum& InRatR)
{
RatNum OutRat;
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
int NewNumer = ((I2Numer * IDenom) - (INumer * I2Denom));
int NewDenom = (I2Denom * IDenom);
OutRat = RatNum(NewNumer,NewDenom);
return OutRat;
}
RatNum RatNum::operator -(const RatNum& InRat)
{
int INumer = ((InRat.Numer)*(-1));
int IDenom = InRat.Denom;
RatNum OutRat(INumer,IDenom);
return OutRat;
}
RatNum RatNum::operator *(const RatNum& InRatL, const RatNum& InRatR)
{
RatNum OutRat;
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
int NewNumer = (I2Numer * INumer);
int NewDenom = (IDenom * I2Denom);
OutRat = RatNum(NewNumer,NewDenom);
return OutRat;
}
RatNum RatNum::operator /(const RatNum& InRatL, const RatNum& InRatR)
{
RatNum OutRat;
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
int NewNumer = (I2Numer * IDenom);
int NewDenom = (INumer * I2Denom);
OutRat = RatNum(NewNumer,NewDenom);
return OutRat;
}
bool RatNum::operator ==(const RatNum& InRatL, const RatNum& InRatR)
{
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
if ((I2Numer * IDenom) == (INumer * I2Denom))
{
return true;
}
else
{
return false;
}
}
bool RatNum::operator <=(const RatNum& InRatL, const RatNum& InRatR)
{
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
if ((I2Numer * IDenom) <= (INumer * I2Denom))
{
return true;
}
else
{
return false;
}
}
bool RatNum::operator >=(const RatNum& InRatL, const RatNum& InRatR)
{
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
if ((I2Numer * IDenom) >= (INumer * I2Denom))
{
return true;
}
else
{
return false;
}
}
bool RatNum::operator <(const RatNum& InRatL, const RatNum& InRatR)
{
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
if ((I2Numer * IDenom) < (INumer * I2Denom))
{
return true;
}
else
{
return false;
}
}
bool RatNum::operator >(const RatNum& InRatL, const RatNum& InRatR)
{
int INumer = InRatR.Numer;
int IDenom = InRatR.Denom;
int I2Numer = InRatL.Numer;
int I2Denom = InRatL.Denom;
if ((I2Numer * IDenom) > (INumer * I2Denom))
{
return true;
}
else
{
return false;
}
}
|
|
|
03-11-2004, 08:37 PM
|
#11
|
Member
Registered: Jul 2003
Location: VA Tech
Distribution: Mandrake 9.1
Posts: 73
Rep:
|
You have the overloaded operators inside the class declaration. If you look at the example I posted it was not a member function of the class. It was a global function that was declared in the .h file and defined with the other class functions in the .cpp, this makes it available to any object using an instance of the class but it is still not a part of the class.
|
|
|
03-11-2004, 09:01 PM
|
#12
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
in that case it does not seem to solve my problem, I want the operators to be part of the class, that way I can compiel it as a shared library without the main() function, then make a seperate program that uses it and the << >> operators without puting any code for <, and >> in the program using the library.
|
|
|
03-11-2004, 10:15 PM
|
#13
|
Member
Registered: Jul 2003
Location: VA Tech
Distribution: Mandrake 9.1
Posts: 73
Rep:
|
Quote:
Originally posted by exodist
in that case it does not seem to solve my problem, I want the operators to be part of the class, that way I can compiel it as a shared library without the main() function, then make a seperate program that uses it and the << >> operators without puting any code for <, and >> in the program using the library.
|
If you do it the way I said you won't need any code for the >> operator in any program because it will be in the included class file. I noticed that you are declaring and defining your class in a single .cpp file this may be why you do not understand what I am saying. Typically you only declare your class and any global functions that go along with it in a .h (header) file and then define the functions in a .cpp file, the only exception to this I can think of is template classes. Then all that will be necessary in any other program is to include the .h file at the top in order to have access to all the classes and functions declared within it. It is not possible to completely seperate the overloaded >> operator from the class that is it being overloaded for, and I don't think it would make much sense to do so.
|
|
|
03-11-2004, 10:18 PM
|
#14
|
Senior Member
Registered: Aug 2003
Location: Portland, Oregon
Distribution: Arch
Posts: 1,374
Original Poster
Rep:
|
I am in my first c++ class, we are supposed to do everything in one cpp file. but I think I understand what you are saying, thank you, I think I need to do some more learning on my own or wait till I am further in the class for this, thank you though :-D
|
|
|
03-11-2004, 10:29 PM
|
#15
|
Member
Registered: Jul 2003
Location: VA Tech
Distribution: Mandrake 9.1
Posts: 73
Rep:
|
Quote:
Originally posted by exodist
I am in my first c++ class, we are supposed to do everything in one cpp file. but I think I understand what you are saying, thank you, I think I need to do some more learning on my own or wait till I am further in the class for this, thank you though :-D
|
Well it is nice to see you working on operator overloading already. They spoon feed us this stuff when I was starting.
|
|
|
All times are GMT -5. The time now is 03:28 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|